整体思路

一般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;
} // 其它的情况
}

最新文章

  1. JavaScript中的继承(原型链)
  2. 禁用gridview默认点击效果
  3. MAC PHP MARK
  4. [jQuery] $.grep使用
  5. Php模板引擎Smarty安装和配置
  6. hdoj1242(dfs 剪枝 解法)
  7. Java设计模式:代理模式(一)
  8. WC2006水管局长(加强)
  9. FFmpeg示例程序合集-Git批量获取脚本
  10. qtp中type方法的按键常量
  11. 页面中去除浮动 clear:both
  12. vue中,class与style绑定
  13. header 和http状态码
  14. 如何更新clob类型的内容
  15. 解决p4c安装时protobuf未定义引用的错误
  16. GreenPlum安装greenplum-cc-web监控
  17. cf463d
  18. 性能计数器监控typeperf
  19. java语言编程入门
  20. [翻译] LLSimpleCamera

热门文章

  1. STM32之CAN通讯接收过滤器过滤分析
  2. CISP/CISA 每日一题 六
  3. 设计模式六大原则(一):单一职责原则(Single Responsibility Principle)
  4. 深度学习 Deep Learning UFLDL 最新Tutorial 学习笔记 3:Vectorization
  5. 在同一个局域网下实时访问vue项目,移动端也可以。
  6. (转)RMAN-06054: media recovery requesting unknown archived log for thread...
  7. chmod用数字来表示权限的方法
  8. mootools常用特性和示例(基础篇2)
  9. 如何获取AppStore软件安装包的路径
  10. .dmp文件导出使用示例