特定版本的轻量级迁移后自定义代码执行

时间:2011-06-29 20:10:32

标签: iphone ios4 core-data core-data-migration

我在Core Data中有2个对象模型(比如v1和v2)。此迁移适用于轻量级迁移。现在,我希望在迁移后执行自定义代码,但仅在迁移从v1到v2时执行。稍后如果我介绍v3,我不希望自定义代码被执行。

有办法做到这一点吗?

提前致谢, 阿努邦

6 个答案:

答案 0 :(得分:10)

以下是如何处理这种情况,基本上是通过使用商店的元数据,正如Apple工程师在WWDC 2010上所建议的那样:

  • 打开商店(使用迁移选项)
  • 检查自定义密钥的元数据,例如“DonePostProcessing”
  • 进行后期处理......
    • 填充派生属性
    • 插入或删除对象
    • 设置商店元数据(“DonePostProcessing”= YES)
  • 保存更改和元数据

或多或少,像



- (void)loadStoreWithMigration:(NSURL *)url {
    ...

   store = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: nil URL: url options: opts error: &err];

   m = [store metadata];
   key = @”DonePostProcessing”;
   if (m && ([[m objectForKey: key] integerValue] < 2) ){
      [self doPostProcessingInContext: context];
      m2 = [[m mutableCopy] autorelease];
      [m2 setObject: [NSNumber numberWithInteger: 2] forKey: key];
      [store setMetadata: m2];

      ok = [context save:&err];
   }

}

答案 1 :(得分:1)

可能有更好的方法,买这个应该有效:

通过将实体保存在名为“Information”的Core Data中并拥有名为“CoreDataVersion”的属性来跟踪数据库版本。

迁移代码完成后,添加代码以检查核心数据中的版本号。

如果“CoreDataVersion”的值为“v1”且您的应用现在为“v2”(可以对每个版本进行硬编码),请执行其他自定义代码,然后将新版本写回数据库。 / p>

如果您已经向用户发布了“v1”,只需说明如果DB中没有“CoreDataVersion”,那么它就是“v1”。

答案 2 :(得分:1)

- (void) _performMaintanaceUpdate:(NSUInteger) newVersion oldVersion:(NSUInteger) oldVersion {
            if (newVersion>=1020500 && oldVersion < 1020500) {
                NSString *storePath = [[PreferenceDataModel getDataPath] stringByAppendingPathComponent: @"wcal.sqlite"];
                NSFileManager *fileManager = [NSFileManager defaultManager];
                if ([fileManager fileExistsAtPath:storePath]) {
                        [fileManager removeItemAtPath:storePath error:NULL];
                }
                [PreferenceDataModel setVersionOfLastMaintanace:newVersion]; 
            }
}

 (void) _checkAndPerformMaintenance{
    NSString* strVersion = [PreferenceDataModel getApplicationVersion];
    //legal version is xx.xx.xx where x is a dec digit 1.2 or 1.2.33 is legit 
    NSUInteger ver = 0;
    NSUInteger finalVer = 0;
    int t = 3; 

    for (int i=0; i<[strVersion length]; i++) {
        char c = [strVersion characterAtIndex:i];
        if (isdigit(c)) {
            ver*=10;
            ver+=c - 48;
        }
        else {
            finalVer+= ver * pow(100, t--); 
            ver = 0;
        }
    }
    finalVer+= ver * pow(100, t);
    [self _performMaintanaceUpdate:finalVer oldVersion:[PreferenceDataModel getVersionOfLastMaintanace]];
}

这就是您检索应用版本的方式

+(NSString *) getApplicationVersion {
    return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
}

答案 3 :(得分:1)

在创建执行自动迁移的持久性存储之前,请确定是否要迁移到版本2.如果有,请设置一个标记以在迁移发生后执行更改。

要确定您要迁移的内容,请执行以下操作:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
NSString *version = [managedObjectModel.versionIdentifiers anyObject];

版本标识符在Xcode中设置。

答案 4 :(得分:1)

另一种方法是从v1到v2进行自定义数据迁移。首先查看http://www.timisted.net/blog/archive/core-data-migration/

答案 5 :(得分:0)

另一种对我有用的解决方案:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSInteger currVersion = [defaults integerForKey:@"dataModelVersion"];
    NSString *version = [managedObjectModel.versionIdentifiers anyObject];
    if (currVersion == 0) {
        [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"];
    }
    else if (currVersion < [version integerValue]) {
        NSLog(@"Migration Code");
        [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"];
    }