• ios app初始化和数据迁移的设计思路


    整体思路

    一般app启动之后,都有一个初始化的过程。

    此外兴许app升级,还须要考虑数据迁移。所以初始化和数据迁移的框架。在初期的版本号就要考虑好

    总结一下我们的app採取的方案:

    1、在持久化的文件夹内(比方UserDefaults或者Documents文件夹),用一个字段保存老版本

    2、在開始初始化之前,读取老版本。以及当前版本

    3、假设该应用是第一次载入,那么老版本就取不到(由于是初次载入,这个字段还没有保存),那么就能够运行初始化过程。假设取到了老版本。就不运行初始化

    4、初始化完毕之后,运行数据迁移。

    由于有老版本和新版本,所以能够通过对照,实现增量式的迁移

    5、上述动作都完毕之后,刷新老版本

    6、下次正常启动,就不会再初始化,也不会运行数据迁移了;假设是安装新版本号,因为当前版本号号刷新,又会触发数据迁移

    用户切换账户的场景

    上面说的是比較简单的场景。假设应用同意多用户切换账号,并且不同用户的数据是分离的,就更复杂一些

    首先标识老版本的字段不能保存在UserDefaults里,由于UserDefaults是用户共享的。这样当A用户初始化之后,老版本就存在了。

    切换到B用户,发现老版本已存在。则不会运行初始化,事实上这时候B用户的数据文件还没有创建好。所以须要把老版本存在单独的地方。比方每一个用户各自的sqlite文件里

    然后,读取老版本的时候。也要依据用户的独立标识去查询

    改进

    眼下临时是把老版本保存在sqlite里,可是这样首次读取的时候。推断逻辑比較麻烦。须要推断sqlite文件是否存在。然后要推断table有没有。最后才干取值。假设用文本保存可能会略微方便一点,比存在sqlite里,少了一个推断table是否存在的步骤

    示意代码

    -(BOOL) needInit
    {
        return [oldVersion isEqual: @"0"];
    }
    
    -(NSString*) oldVersion
    {
        return oldVersion;
    }
    
    -(NSString*) currentVersion
    {
        return currentVersion;
    }
    
    #pragma mark - private method
    
    -(void) initOldVersion
    {
        // 数据库文件不存在。oldVersion设为0
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *dbFilePath = [YLSGlobalUtils getDatabaseFilePath];
        if(![fileManager fileExistsAtPath:dbFilePath]){
            oldVersion = @"0";
            return;
        }
        
        // 数据库文件打开失败。oldVersion设为0
        FMDatabase *db = [FMDatabase databaseWithPath:dbFilePath];
        if(![db open]){
            oldVersion = @"0";
            return;
        }
        
        // tb_clientstage表不存在,oldVersion设为0
        int tableCount = 0;
        FMResultSet *rs = [db executeQuery:@"select count(*) as count from sqlite_master where type='table' and name='tb_clientstage'"];
        if([rs next]){
            tableCount = [rs intForColumn:@"count"];
        }
        if(tableCount == 0){
            oldVersion = @"0";
            [db close];
            return;
        }
        
        // 设置oldVersion
        rs = [db executeQuery:@"select * from tb_clientstage where id = '1' and tableno = '0'"];
        if([rs next]){
            oldVersion = [rs stringForColumn:@"version"];
        }else{
            oldVersion = @"0";
        }
        [db close];
    }
    
    -(void) initCurrentVersion
    {
        NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
        NSString* versionNum =[infoDict objectForKey:@"CFBundleVersion"];
        currentVersion = versionNum;
    }

    然后,是否进行初始化的推断:

    clientInfo = [YLSClientInfo new];
    
    if([clientInfo needInit]){
        [self createEverythingForFirstTime];// 初始化时才运行
    }
    [self allTheTime];// 不论什么时候都运行
    
    [migrationHelper doMigration:clientInfo];

    增量迁移:

    -(void) doMigration:(YLSClientInfo*)clientInfo
    {
        NSString *oldVersion = [clientInfo oldVersion];
        NSString *currentVersion = [clientInfo currentVersion];
        
        // 正常登陆。不须要数据迁移
        if([oldVersion isEqualToString:currentVersion]){
            return;
        }
        
        // 全新安装,非升级,不须要数据迁移
        if([oldVersion isEqualToString:@"0"]){
            return;
        }
        
        // 下面均是版本号升级,须要数据迁移
        if([oldVersion isEqualToString:@"1.0.0"]){
            [script1 doMigration];
            [script2 doMigration];
            [script3 doMigration];
            [script4 doMigration];
            return;
        }
        
        // 其它的情况
    }


  • 相关阅读:
    Python Day13:开放封闭原则、函数装饰器、全局局部变量
    Python Day12
    Python Day11
    Python Day10
    drf框架
    drf框架
    drf框架
    drf框架
    vue框架
    vue框架
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7225481.html
Copyright © 2020-2023  润新知