我需要做些什么才能让Core Data自动迁移模型?

时间:2009-06-19 14:09:46

标签: core-data

我已阅读有关Core Data模型的自动/轻量级迁移的文档 - 但我在实现它时遇到了问题。

据我所知,应用程序应该注意到它所拥有的模型和设备上存在的模型已经不一样了。如果您只添加了属性或关系以及类似的简单更改,则应自动升级模型。

任何指针 - 我是否需要在Xcode中设置内容?

10 个答案:

答案 0 :(得分:138)

我现在发现这很简单 - 一旦你知道在哪里看。

在我的AppDelegate中,我设置了NSPersistentStoreCoordinator - 您需要为此添加一些选项以告诉它处理自动迁移:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
    NSLog(@"Problem with PersistentStoreCoordinator: %@",error);
}

然后你需要在xCode中做一个小技巧:

  1. 选择您的xcdatamodel文件
  2. 选择顶部的设计菜单 - 然后选择数据模型 - 然后选择添加模型版本
  3. 然后,您的xcdatamodel文件将被移动到一个与您的xcdatamodel文件同名但扩展名为xcdatamodeld的新目录中 - 此目录中将有第二个文件,名称中包含2。选择新文件,然后选择设计 - >数据模型 - >设置当前版本(in Xcode 4 you do this
  4. 如果您已经进行了导致项目不兼容的更改 - 请从原始xcdatamodel文件中取出这些更改。如果您还没有进行更改 - 那么只需编辑2.xcdatamodel文件(您刚制作当前版本的文件)。
  5. 现在,当您将此版本安装到具有旧型号的设备上时,它会自动将该型号升级到新型号。
  6. 这看起来很棒,也很简单 - 但我认为在更改模型时需要在开发过程中小心 - 否则你将不得不为每个更改创建一个新版本。

    我认为我将要做的是保留所有已更改的文件,然后在我准备好部署更新后,我将删除所有中间文件,并使用最旧和最新的模型进行部署。 / p>


    更新(2011年7月15日):

    感谢@ rockstarberlin指出Apple上有更新的文档:

    Xcode 4: Setting a Managed Object Model’s Current Version

    更新:2013年8月19日更好的链接:

    https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html

答案 1 :(得分:13)

这非常有帮助。苹果文档 - 像往常一样 - 非常不完整。我建议做一个干净的构建,因为当我在进行这些更改后第一次运行时遇到错误“无法将模型与两个不同的实体xxx合并”。干净的构建修复了它。

答案 2 :(得分:6)

Grouchal的答案是完美的...但是如果你仍然拥有“无法将模型与两个不同的实体xxx合并”,即使在多次清理构建之后......你可能会遇到如何使用managedObjectModel的问题加载......看看这个......这帮我解决了..

core data migration problems

答案 3 :(得分:3)

另外,如果你偶然发现这篇文章,就像我做的那样,在获得“用于打开商店的模型与用于创建商店的模型不兼容”错误后,您只是使用模拟器进行调试并希望完全替换已安装的旧型号,您只需重置模拟器应用程序或从模拟器中删除您的应用程序也可能会起作用。

在我阅读这里的帖子之前我没有尝试过这一点,此时我意识到我已经在模拟器中安装了应用程序然后更改了模型,导致上述运行时错误。

答案 4 :(得分:1)

要跟进Santthosh的回答,我想我会在这里发布代码片段。您需要使用initWithContentsOfURL:而不是mergedModelFromBundles:创建managedObjectModel,否则您将收到错误:

  

无法合并两种不同的模型   实体XXX和XXX

如果您的模型文件名为“Model”,则以下是创建managedObjectModel的方法:

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

归功于this blog post

答案 5 :(得分:1)

Xcode 4中的菜单略有改变。这里是如何在Xcode 4中进行描述的:

Xcode 4: Setting a Managed Object Model’s Current Version

答案 6 :(得分:1)

我已经有这个问题多年了,我尝试了所有这些答案都无济于事。今天我终于弄清楚我做错了什么。非常简单的问题,但我忽略了它。在创建数据模型的较新版本时,如果您要添加列,请确保将它们标记为可选。如果不这样做,则简单迁移将不起作用,因为不会填充新的列值。

只要我确定我的新列已经选中“可选”,我就会再次尝试迁移它并且有效。

答案 7 :(得分:1)

由于存在不同的问题,我偶然发现了这篇文章,但错误是“用于打开商店的模型配置与用于创建商店的模型配置不兼容。

这是我的问题和解决方案。在我的模型中,我使用 配置 。我有一些实体存储在一个文件中,其他实体存储在第二个文件中。 (我有一些可能需要定期下载的默认设置,将它们整合到一起会是一个令人难以置信的痛苦)。无论如何,我创造了一个新的实体。该程序似乎运行正常,但每当我退出时,我都会遇到上述错误。

解决方案是查看我的配置,意识到我有一个当前不在任何配置中的实体,并将其添加到一个配置中。像梦一样运行。

这不会解决OP的问题。但也许一些沮丧的人通过谷歌登陆这里将在我所在的船上:)

答案 8 :(得分:0)

iOS 4.0 +

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

答案 9 :(得分:0)

轻微编辑@Grouchal上面针对Xcode第5版的精彩说明:

旧: 2.选择顶部的设计菜单 - 然后选择数据模型 - 然后选择添加模型版本

版本5+: 2.选择编辑器菜单,然后选择添加模型版本...,键入您的版本名称和基于模型(从列表中选择您的原始模型)