Core Data自动轻量级迁移——从无版本控制的数据模型切换到有版本控制的数据模型



我正在尝试执行轻量级迁移,但是由于创建初始数据模型的方式,我遇到了一个问题。最初的数据模型没有版本化,所以现在有以下代码:

-(NSManagedObjectModel *)managedObjectModel {
    //NSLog(@"%s", __FUNCTION__);
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    //managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
    NSString *mainPath = [[NSBundle mainBundle] pathForResource:@"myDatabase" ofType:@"momd"];
    NSURL *mainMomURL = [NSURL fileURLWithPath:mainPath];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:mainMomURL];
    return managedObjectModel;
}

返回错误:*由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'* -[NSURL initFileURLWithPath:]: nil字符串参数'

我很确定这是因为最初的数据模型-我在我的应用程序中部署给很多人已经-有妈妈扩展,而不是momd扩展。但是,如果我把它拿出来,回到

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

我得到错误:终止应用程序由于未捕获异常'NSInvalidArgumentException',原因:'不能合并模型与两个不同的实体命名为…

我希望这不是第一次有人遇到这种情况…我是否可以做些什么,以便为所有当前用户成功迁移?

好的,进展顺利。根据Yuji在这个链接中的回答:找不到mod文件:Core Data问题

,我决定用这句话:

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

在设备上安装旧版本,添加一些数据,使用新版本进行干净构建,然后在设备上安装新版本后,所有内容都正确更新。准备在模拟器上再试一次,和其他目标一起。这很疯狂,你有时会觉得你做同样的事情,有时会得到不同的结果吗?我将发布更新一旦我得到进一步....

编辑:一些有趣的进展。这个项目最初是我的一个应用程序,在两个应用程序部署到应用程序商店之后,我添加了另一个具有类似代码的应用程序(作为单独的目标),以便代码重用。因为它们的数据库本质上是相同的,所以我只是对两者使用了相同的xcdata模型。一直都很好,直到…我开始处理这个迁移问题。结果是,上面managedObjectModel的代码对项目中的原始目标有效,但对新目标无效。

然后,我发现Marcus Zarra的评论:

他可能要么重命名模型,要么建立一个版本,两者兼而有之这将在构建目录中留下一个旧的编译过的.mom文件。这是我看到的导致这个错误的第一个原因。

在此链接中:Core Data: Error, " cannot Merge Models With Two Different Entities Named 'foo' "

好吧,也许我们现在有点进展了。问题是——我现在是否需要将我的其他原始数据模型引入项目,并同时更新IT ?我们从这里往哪里走?

编辑:好的,我想我在这个问题上取得了一些不错的进展。请随时纠正我的任何以下。但是,从我目前了解到的情况来看:

Bundle Name应该保持不变,否则迁移会出现问题。这意味着,在我的理解中,可能会保留产品名称。但是,它看起来像是改变Bundle Display Name(它不同于Bundle Name,也在app-info中设置)。plist文件)不会造成任何损害,而且实际上在一开始就实现了更改Bundle Name的目的。

另外(我最初的问题!),从无版本控制的数据模型切换到有版本控制的数据模型是完全可以的,事实上,预计这是第一次迁移时通常发生的情况。所以没有问题。

另一个教训-数据模型名称和.sqlite文件名不一定相同!我的一个(许多)错误是在查找mod文件时使用了.sqlite文件名。当你寻找mod文件时(当在应用委托中设置managedObjectModel时)-使用xcdatamodel文件的名称!沿着这些路线,我不确定在迁移期间我是否应该使用"mergedModelFromBundles"或"initWithContentsOfURL"。一旦我有了正确的文件名,initWithContentsOfURL工作得很好(我仍然有一些测试要做,但我已经让它与两个应用程序目标一起工作,在模拟器和设备上。分数。

关于xdata模型和xCode 4的一句话-真是令人头疼。由于某些原因,我无法删除xCode 4中临时/未使用/不需要的数据模型版本。因此,我不得不做很多花哨的步骤来使这些正确,包括删除模型本身(仅引用),通过在Finder中使用"显示包内容"进行更改,并将模型添加回去。做这件事的时候要非常小心。我发现一件非常有趣的事情是,我确实需要两个xcdatamodel,一个用于我正在使用的每个应用程序目标,并且xcdatamodel的标题需要与以前部署的版本相匹配才能迁移工作。不仅如此,当前模型还需要是没有数字的模型——它需要与我部署的应用程序中的模型名称完美匹配。

这真的很棘手,因为当我重命名模型并将不同的模型设置为当前版本时,xCode 4并不总是想要合作。一个有趣的事情是,当我必须设置一个模型在树中另一个模型的下面作为当前模型时,xcode在运行时不喜欢这样。所以我不得不在Finder中打开。xcodeproj文件(关闭应用程序),显示包内容,编辑项目。Pbxproj文件,并更改数据模型的顺序,将当前数据模型放在列表的顶部。

嗯,我想这基本上就是全部了。如果我想到别的,我就把它加在这里。我还想再测试一下,但我希望我学到的一些东西能帮助到别人。我知道我做了很多粗鲁的事情,但绝望的时刻需要绝望的措施,当我们了解得更好时,我们就会做得更好……

最新更新