我在Core Data中有2个对象模型(比如v1和v2)。此迁移适用于轻量级迁移。现在,我希望在迁移后执行自定义代码,但仅在迁移从v1到v2时执行。稍后如果我介绍v3,我不希望自定义代码被执行。
有办法做到这一点吗?
提前致谢, 阿努邦
答案 0 :(得分:10)
以下是如何处理这种情况,基本上是通过使用商店的元数据,正如Apple工程师在WWDC 2010上所建议的那样:
或多或少,像

- (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"];
}