【问题标题】:iOS Core Data Migration big IssueiOS 核心数据迁移大问题
【发布时间】:2014-02-12 07:49:27
【问题描述】:

当我开始开发应用程序时,我有一个 核心数据模型,其中包含 5 个实体(名为 Visitors, UnreadMessages, ContactStatuses, UserVCardUser)。该应用程序已在应用程序商店上线.. 没问题.. 现在我必须添加一些需求更改,因此核心数据模型通过添加 2 个以上实体 (命名为 AudioSupportedWindowsAudioMessages)

所以根据很多文章、SO 帖子和苹果文档,迁移的方法是 LightWeight 迁移,因此我添加了以下代码

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

在我的persistentStoreCoordinator 方法中。但它总是给出 Can't find model for source store 错误。

之后,我根据此链接 Core Data - Default Migration ( Manual ) 使用迁移映射开始手动迁移

但是当我运行它时,我得到了源模型和目标模型,但它们是相同的,即它们都包含 5 个实体。我收到此错误 The model used to open the store is incompatible with the one used to create the store

他们陷入了严重的麻烦,现在正在解决这个问题……任何帮助将不胜感激。

编辑 1

- (NSManagedObjectModel *)managedObjectModel
{
    if (managedObjectModel != nil)
    {
        return managedObjectModel;
    }
    
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"UserData" withExtension:@"momd"];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    return managedObjectModel;
}

【问题讨论】:

  • 在应用程序部署给用户后,您绝不能更改应用程序的数据模型。您需要创建模型的新版本,以便它们都在应用程序中。如果您已更改它,则需要返回到代码的先前版本(使用 git 或您用于版本控制的任何东西),或从先前的备份。然后使用您的应用中包含的两个模型重试。
  • 您说永远不要更改数据模型真是太奇怪了。应用程序可能会发生需求更改或添加。然后您肯定需要更改模型。跨度>
  • 不,您是说您的应用已在应用商店上线。然后,您可能有多个用户将您的应用程序与您当前的数据模型一起使用。如果您需要更改该数据模型,则不能只更改当前模型,因为这将禁用您的应用程序使用当前核心数据存储(因为数据模型不再与存储匹配)。我的意思是你需要在xcode中创建一个新版本(一个副本),然后更改副本。这样,您的应用现在包含两个版本的数据模型:一个在您的用户拥有的应用中使用,另一个是您要迁移到的新模型
  • 他说的是你不能改变你的数据模型,而是创建它的新版本并修改新版本。
  • ohk.. 所以问题仍然是将模型迁移到更改后的模型..

标签: ios objective-c core-data


【解决方案1】:

确保原始模型和新模型都包含在您的应用中,在模型包中。您不能只包含新模型并期望它进行迁移(尽管这样会更酷),这不是它的工作方式。

您的新模型应标记为“当前模型”。您的旧文件仍然可以读取旧文件。如果新模型中没有旧模型中不需要的新字段,那么轻量级翻译应该可以工作。

【讨论】:

  • 我在xcdatamodeld 中有两个模型文件,并且新的模型文件被选为当前模型..
  • 你是用干净的(冰雹玛丽)建造的吗?
  • 我在应用商店下载了版本,使用了该应用程序,然后使用 Xcode 将应用程序部署到具有新版本模型的设备上。
【解决方案2】:

看起来您认为您发布的模型与您实际发布的模型不同。 检查您提交给 iTC 的内容:

  • 转到 Organizer/Archives 找到您提交的存档,然后“在 Finder 中显示”
  • 找到模型版本文件:VersionInfo.plist
  • 打开 plist 查看每个实体的哈希值

将哈希值与当前模型的哈希值进行比较(只需创建一个新的存档),您应该能够找到已更改的那个。

【讨论】:

  • 两个版本中的实体具有相同的哈希值。它们的唯一区别是新版本中添加的实体。
  • 还有一件事,不管它是否重要,这里有 4 个文件而不是 3 个 UserData.mom、UserData 2.mom、VersionInfo.plist 和 UserData 2.omo
  • 在 VersionInfo.plist 中,您应该有两个模型:一个具有原始 5 个实体,一个具有 7 个实体的“模型 2”。
【解决方案3】:

这可能是我运行过几次的问题。从应用商店下载您的应用并运行它,以便创建托管对象商店。然后在您的 xcode 中实例化您的持久存储协调器之前尝试以下操作:

// Model.momd/Model is the path of the previous model. Make sure it's correct
NSURL *oldUrl = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"Model.momd/Model"] withExtension:@"mom"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:oldUrl];
NSLog(@"Old model version hashes: %@", model.entityVersionHashesByName);

// Change model with your model name
NSURL *currentModelUrl = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"Model"] withExtension:@"momd"];
NSManagedObjectModel *currentModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:currentModelUrl];
NSLog(@"Current model version hashes: %@", currentModel.entityVersionHashesByName);



// storeUrl is the path to the persistent store, created by the app store version
NSDictionary *metadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeUrl error:nil];
NSLog(@"Store metadata: %@", metadata);

元数据实体哈希值应与旧模型版本哈希值相同。如果不是,那么您拥有的原始型号与您随附的型号不同。您可能需要在源代码控制存储库中找到旧模型(希望您有一个),否则您可以尝试手动更改这些值。

【讨论】:

  • 只是这样做了……5个实体哈希值没有区别,唯一不同的是当前模型哈希值中新添加的2个实体。
  • 那么老模型和当前模型的区别就是2个新实体,元数据和老模型完全一样?
  • 嗯,那你根本不应该有这个问题
  • 这就是要我死的原因……我似乎找不到任何问题,但它不会迁移
【解决方案4】:

感谢大家的帮助……我使用轻量级迁移解决了它。我所做的是删除我的 xcdatamodeld,从 App Store 上的那个重新创建它,制作新的数据库文件,添加新的模型版本。不知何故我没有知道它是如何工作的……

但他们很高兴它有效:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-04
    • 2013-11-26
    • 1970-01-01
    • 2011-09-14
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多