核心数据版本控制和使用自定义策略迁移

use*_*500 5 core-data objective-c core-data-migration ios

我发现文档非常有限,我的问题解决方案无处可寻.

我需要添加新实体(与现有实体的关系).还添加并重命名现有实体的一些属性.

轻量化的例子:

旧模型有一个Item具有一个属性的实体name.

在新模型中,我想要Item一个新属性dateAdded并重命名nametitle.此时,如果dateAdded是可选的或给定默认值,我可以使用轻量级迁移功能.如果我错了,请纠正我.

但我也想添加List带有title属性的新实体.并增加了许多关系.列表可以为空或有很多项目.项目必须完全引用一个列表.

所以我很困惑我要做的一切以及订单是什么.

  1. 通过禁用轻量级迁移功能启用迁移(NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:NO], NSInferMappingModelAutomaticallyOption, nil];).

  2. 创建新版本的模型.在那里,我做了我想做的改变.

  3. 创建一个新的映射模型.来源是旧模型,目标是新模型.在ItemToItem我设置title$source.name.

除了Xcode在使用映射模型时仍然崩溃我不知道接下来该做什么.我想我必须List在上下文中创建一个实例,并且因为关系策略而使所有项引用它.我应该使用自定义NSEntityMigrationPolicy来做到这一点.有任何帮助来完成这一挑战吗?

use*_*500 9

好吧,我做到了......

我的前3个步骤是正确的.继续方案:

ADD4.做一个ItemToItemMigrationPolicy,一个子类NSEntityMigrationPolicy.覆盖:

- (BOOL)beginEntityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
{
    List* list = (List*)[NSEntityDescription insertNewObjectForEntityForName:@"List" inManagedObjectContext:[manager destinationContext]];
    list.name = @"Default list";

    return YES;
}

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
{
    Item* item = (Item*)[NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName] inManagedObjectContext:[manager destinationContext]];
    item.dateAdded = [NSDate date];
    task.title = [sInstance valueForKey:@"name"];

    [manager associateSourceInstance:sInstance withDestinationInstance:item forEntityMapping:mapping];

    return YES;
}

- (BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
{

    NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"List"];
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name LIKE 'Default list'"];
    fetchRequest.predicate = predicate;

    NSError* fetchRequestError = nil;
    NSArray* listsArray = [manager.destinationContext executeFetchRequest:fetchRequest error:&fetchRequestError];
    if (fetchRequestError) {
        NSLog(@"%@", fetchRequestError.localizedDescription);
    }
    List* list = [listsArray lastObject];

    ((Item*)dInstance).list = list;

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

ADD5.在Xcode中,在映射模型中将ItemToItem迁移策略设置为自定义ItemToItemMigrationPolicy值.

ADD6.使新模型版本成为当前版本并从新实体或已更改实体生成(替换)类.

ADD7.对代码进行更改,例如item.name不再有效.现在是item.title.清理项目并运行.