Core Data自动轻量级迁移 - 从无版本数据模型切换到版本化数据模型

时间:2011-10-09 03:19:16

标签: core-data version-control migration core-data-migration xcdatamodel

我正在尝试执行轻量级迁移,但由于我创建初始数据模型的方式,我遇到了问题。初始数据模型未进行版本控制,因此现在使用以下代码:

-(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 string parameter'

我很确定这是因为最初的数据模型 - 我在我的应用程序中部署到许多人的那个 - 具有妈妈扩展而不是妈妈扩展。但是,如果我把它拿出来并恢复到

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

我收到错误:由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因是:'无法将模型与名为...的两个不同实体合并...

我希望这不是第一次有人遇到这种情况......我能做些什么让我能够成功迁移所有现有用户?

1 个答案:

答案 0 :(得分:0)

好的,取得进展。根据Yuji在此链接中的回答:Can't find momd file: Core Data problems

,我决定选择这条线:

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

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

编辑: 一些有趣的发展。目前,这个项目最初是作为我的一个应用程序开始的,我在其他应用程序中添加了类似代码(作为单独的目标),用于代码重用,两个应用程序都部署到应用程序商店。由于他们的数据库基本相同,我只使用了相同的xcdatamodel。哪个工作正常,直到...我开始处理这个迁移问题。事实证明,上面的managedObjectModel代码适用于项目中的原始目标,但不适用于新目标。

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

  

他可能要么重命名模型,要么设置一个版本   这将在构建目录中保留一个旧的编译.mom文件。   这是我见过的这个错误的第一个原因。

在此链接中:Core Data: Error, “Can't Merge Models With Two Different Entities Named 'foo' ”

好吧,也许我们现在到了这里的某个地方。问题是 - 我现在需要将我的其他原始数据模型引入项目,并更新IT吗?我们从哪里开始?

编辑:好的,我认为我在这个问题上取得了一些进展。请随时通过以下任何方式纠正我。但是,从我到目前为止所学到的:

捆绑名称应保持不变,否则迁移会出现问题。根据我的理解,这意味着可能将产品名称保留为原样。但是,似乎更改Bundle显示名称(与Bundle Name不同,并且也在app-info.plist文件中设置)不会伤害事物,实际上实现了目的或更改了Bundle Name in第一名。

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

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

关于xcdatamodels和xCode 4的一句话 - 真是令人头疼。出于某种原因,我无法删除xCode 4中的临时/未使用/不需要的数据模型版本。所以,我必须做很多花哨的步法才能使这些正确,包括删除模型本身(仅限参考) ),使用Finder中的“显示包装内容”进行更改,然后重新添加模型。执行此操作时应非常小心。我发现一个非常有趣的事情是我需要两个xcdatamodel,一个用于我正在使用的每个应用程序目标,并且xcdatamodel的标题需要与先前部署的版本的标题匹配才能迁移到工作。不仅如此,当前模型需要是没有数字的模型 - 它需要在我部署的应用程序中完美匹配模型的名称。

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

嗯,我认为这主要是一切。如果我想到别的什么,我会在这里添加它。还是想再测试一下这个,但我希望我学到的一些东西会帮助别人。我知道我做了很多讨厌的事情,但是绝望的时候需要采取绝望的措施,当我们知道的更好时我们做得更好......希望这会有所帮助。