核心数据迁移:未调用NSEntityMigrationPolicy中的方法。

时间:2012-11-21 12:49:22

标签: iphone objective-c ios ios6 core-data-migration

我有两个模型版本--12和13.然后我创建了一个xcmappingmodel-File,其中包含源12和目标13。

我将NSEntityMigrationPolicy子类化,并将我的类添加到mappingmodel-File到所需的实体。

@interface EndDateMigrationPolicy : NSEntityMigrationPolicy

enter image description here

在我的设备上安装和旧版本(11)后,我使用模型版本13安装当前状态 - 应用程序运行,但我的迁移方法未被调用。我错过了什么吗?

编辑:使用这些选项是否正确?

    NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES,
                         NSInferMappingModelAutomaticallyOption: @YES};

2 个答案:

答案 0 :(得分:3)

我将尽力回答你,我已经经历了几次核心数据迁移,所以我知道它是多么痛苦。对于一个你不能希望必须让你的迁移与这些选项一起工作,因为你想要做的事实上不是轻量级迁移,而是你告诉它进行轻量级迁移。

基本上我们假设您需要在两个版本之间进行非轻量级迁移,在您的情况下为11和12.您需要做的是:

1-> 12轻量级 12-> 13自定义迁移 13->(未来版本)轻量级迁移

可能有更好的解决方案,但我还没有找到它。

这里有一些代码可以帮助你(最困难的部分,我不记得所有事情),在此代码之前我将数据库复制到备份,所以基本上备份数据库是旧的,商店是你的新人(空的)

NSString *path = [[NSBundle mainBundle] pathForResource:<YOUR MODEL NAME> ofType:@"cdm"];

NSURL *backUpURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"<YOUR MODEL NAME>MigrationBackUp.sqlite"]; //or whatever you want to call your backup
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"<YOUR MODEL NAME>.sqlite"];
NSError *err2 = nil;
NSDictionary *sourceMetadata2 =
[NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
                                                           URL:backUpURL
                                                         error:&err2];
NSManagedObjectModel *sourceModel2 = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]

                                                                 forStoreMetadata:sourceMetadata2];
NSManagedObjectModel *destinationModel2 = [self managedObjectModelForVersion:@"1.4"]; //Yeah your gonna have to get your mapping model , I'll give you this code too later
NSString *oldModel = [[sourceModel2 versionIdentifiers] anyObject];
NSLog(@"Source Model : %@",oldModel);
NSMappingModel *mappingModel = [[NSMappingModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]];

if (mappingModel != nil) {
    for (NSString * identifier in [mappingModel entityMappings]) {
        NSLog(@"Mapping > %@",identifier);
    }
}

然后只使用您的源和目标创建一个迁移器。

此后这也是一个困难的部分:

    BOOL success = [migrator migrateStoreFromURL:backUpURL
                                        type:NSSQLiteStoreType
                                     options:nil
                            withMappingModel:mappingModel
                            toDestinationURL:storeURL
                             destinationType:NSSQLiteStoreType
                          destinationOptions:nil
                                       error:&err2];

最后但并非最不重要(我说我之前会给你):

- (NSManagedObjectModel *)managedObjectModelForVersion:(NSString*)version {

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
if (BETWEEN_INEX(version, @"1.0", @"1.4")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
} else if (BETWEEN_INEX(version, @"1.4", @"1.5")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model 2"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
} else if (BETWEEN_INEX(version, @"1.5", @"1.6")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model 3"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
} else if (BETWEEN_INEX(version, @"1.6", @"1.7")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model 4"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
}
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
NSManagedObjectModel * oldManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSSet *vIdentifiers = [oldManagedObjectModel versionIdentifiers];
for (NSString * identifier in vIdentifiers) {
    NSLog(@"Old Model : %@",identifier);
}
return [oldManagedObjectModel autorelease];

}

我知道这些只是代码片段,但我真的希望它可以帮助您解决问题,如果您还需要其他任何问题。

答案 1 :(得分:1)

您的NSEntityMigrationPolicy未被调用,因为您将NSInferMappingModelAutomaticallyOption设置为@(YES) - 它应该是@(NO)