【问题标题】:Core Data automatic lightweight migration - switching from unversioned to versioned data modelCore Data 自动轻量级迁移——从非版本化数据模型切换到版本化数据模型
【发布时间】:2011-12-03 19:31:36
【问题描述】:

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

-(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;
}

返回错误:* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSURL initFileURLWithPath:]: nil string parameter'

我很确定这是因为初始数据模型——我已经在我的应用中部署给很多人的模型——具有 mom 扩展而不是 momd 扩展。但是,如果我把它拿出来并恢复到

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

我收到错误:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无法合并具有两个不同实体的模型...

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

【问题讨论】:

  • 希望 Marcus Zarra 参与进来。
  • 有什么想法吗?我错过了什么明显的东西吗?

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


【解决方案1】:

好的,正在取得进展。根据 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 Name 应该保持不变,否则迁移会出现问题。这意味着,据我了解,可能会保留产品名称。但是,似乎更改 Bundle Display Name(与 Bundle Name 不同,也是在 app-info.plist 文件中设置的)并没有什么坏处,实际上达到了目的或更改了 Bundle Name第一名。

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

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

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

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

嗯,我认为这就是一切。如果我想到其他任何东西,我会在这里添加它。仍然想对此进行更多测试,但我希望我学到的一些东西会对某人有所帮助。我知道我做了很多骇人听闻的事情,但绝望的时候需要采取绝望的措施,当我们知道得更好时,我们会做得更好......希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    相关资源
    最近更新 更多