ios iPhone Core Data“自动轻量迁移”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1830079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:40:26  来源:igfitidea点击:

iPhone Core Data "Automatic Lightweight Migration"

iosiphonecore-datacore-data-migration

提问by Eric

I am attempting to update an app that implements a core data store. I am adding an attribute to one of the entities.

我正在尝试更新实现核心数据存储的应用程序。我正在向其中一个实体添加一个属性。

I added the following code to my delegate class:

我在我的委托类中添加了以下代码:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Shoppee.sqlite"]];

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

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        NSLog(@"Error: %@",error);
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator;
}

This was from the following URL: Doc

这是来自以下 URL: Doc

I get the following error when executing the code:

执行代码时出现以下错误:

2009-12-01 20:04:22.877

Shoppee[25633:207] Error: Error

Domain=NSCocoaErrorDomain Code=134130

UserInfo=0x1624d20 "Operation could not be completed. (Cocoa error 134130.)" 2009-12-01 20:04:22.879 Shoppee[25633:207] Unresolved error Error Domain=NSCocoaErrorDomain Code=134130 UserInfo=0x1624d20 "Operation could not be completed. (Cocoa error 134130.)", { URL = file://localhost/Users/Eric/Library/Application%20Support/iPhone%20Simulator/User/Applications/A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1/Documents/MyApp.sqlite; metadata = { NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = { Item = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; Store = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "8DC65301-3BC5-42BE-80B8-E44577B8F8E1"; }; reason = "Can't find model for source store"; }

2009-12-01 20:04:22.877

购物者 [25633:207] 错误:错误

域=NSCocoaError 域代码=134130

UserInfo=0x1624d20“操作无法完成。(Cocoa 错误 134130。)” 2009-12-01 20:04:22.879 Shoppee[25633:207] 未解决的错误错误域=NSCocoaErrorDomain Code=13402130完成。(Cocoa 错误 134130。)”,{ URL = file://localhost/Users/Eric/Library/Application%20Support/iPhone%20Simulator/User/Applications/A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1/Documents/MyApp .sqlite; 元数据 = { NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = { 项目 = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; 商店 = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>;}; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "8DC65301-3BC5-42BE-80B8-E44577B8F8E1"; }; reason = "找不到源存储模型"; }

It looks like I somehow need to include the original data model but I am not sure how to do that. Any suggestions?

看起来我不知何故需要包含原始数据模型,但我不知道该怎么做。有什么建议?

回答by Stian H?iland

To recap/Full guide:

回顾/完整指南:

  1. Before making any change, create a new model version.

    In Xcode 4: Select your .xcdatamodel-> Editor -> Add Model Version.

    In Xcode 3: Design -> Data Model -> Add Model Version.

    You will see that a new .xcdatamodelis created in your .xcdatamodeldfolder (which is also created if you have none).

  2. Save.

  3. Select your new .xcdatamodeland make the change you wish to employ in accordance with the Lightweight Migrationdocumentation.

  4. Save.

  5. Set the current/active schema to the newly created schema.

    With the .xcdatamodeldfolder selected:

    In Xcode 4: Utilities sidebar -> File Inspector -> Versioned Core Data Model -> Select the new schema.

    In Xcode 3: Design > Data Model > Set Current Version.

    The green tick on the .xcdatamodelicon will move to the new schema.

  6. Save.

  7. Implement the necessary code to perform migration at runtime.

    Where your NSPersistentStoreCoordinatoris created (usually AppDelegate class), for the optionsparameter, replace nilwith the following code:

    [NSDictionary dictionaryWithObjectsAndKeys:
                      [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                      [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
    
  8. Run your app. If there's no crash, you've probably successfully migrated :)

  9. When you have successfully migrated, the migration code (step 7) can be removed. (It is up to the developer to determine when the users of a published app can be deemed to have migrated.)

  1. 在进行任何更改之前,请创建一个新的模型版本。

    在 Xcode 4 中:选择您的.xcdatamodel-> 编辑器 -> 添加模型版本。

    在 Xcode 3 中:设计 -> 数据模型 -> 添加模型版本。

    您将看到.xcdatamodel在您的.xcdatamodeld文件夹中创建了一个新文件夹(如果没有,也会创建)

  2. 节省。

  3. 选择新的.xcdatamodel,让你希望使用按照变化轻量级迁移的文档

  4. 节省。

  5. 将当前/活动模式设置为新创建的模式。

    随着.xcdatamodeld选择的文件夹:

    在 Xcode 4: Utilities sidebar -> File Inspector -> Versioned Core Data Model -> 选择新模式。

    在 Xcode 3 中:设计 > 数据模型 > 设置当前版本。

    .xcdatamodel图标上的绿色勾号将移至新架构。

  6. 节省。

  7. 实现必要的代码以在运行时执行迁移。

    在您NSPersistentStoreCoordinator创建的位置(通常是 AppDelegate 类),对于options参数,替换nil为以下代码:

    [NSDictionary dictionaryWithObjectsAndKeys:
                      [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                      [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
    
  8. 运行您的应用程序。如果没有崩溃,您可能已经成功迁移:)

  9. 成功迁移后,可以删除迁移代码(第 7 步)。(由开发人员决定何时可以认为已发布应用程序的用户已迁移。)

IMPORTANT:Do not delete old model versions/schemas. Core Data needs the old version to migrate to the new version.

重要提示:不要删除旧的模型版本/架构。Core Data 需要旧版本迁移到新版本。

回答by Eric

I figured it out.

我想到了。

Design > Data Model > Add Model Version

设计 > 数据模型 > 添加模型版本

回答by davetron5000

For Googlers again, this is what you need to do (assuming you have already set up Lightweight Migration):

对于 Google 员工来说,这就是您需要做的(假设您已经设置了轻量级迁移):

  1. Before making changes, Do Design -> Data Model -> Add Model Version (you will see that a new .xcdatamodelis created in your .xcdatamodeldfolder)
  2. Save
  3. Make your change
  4. Save
  5. Run App
  1. 在进行更改之前,Do Design -> Data Model -> Add Model Version (你会看到.xcdatamodel在你的.xcdatamodeld文件夹中创建了一个新的)
  2. 节省
  3. 做出改变
  4. 节省
  5. 运行应用

Step #1 is crucial for making this work. I ran into this problem because I had followed these steps to add a new field. That worked. I added a second new field, but forgot to "Add Model Version", and things blew up.

第 1 步对于完成这项工作至关重要。我遇到了这个问题,因为我按照这些步骤添加了一个新字段。那奏效了。我添加了第二个新字段,但忘记了“添加模型版本”,事情就搞砸了。

回答by Gmu

Also for googlers.. Simple rule, never delete/edit any old numbered version. When you Add Model Version the number suffix will increase as 2..3..4 meaning 2 is the oldest 3 next etc.. but the Current one to edit is the unnumbered version.

也适用于 googlers.. 简单的规则,永远不要删除/编辑任何旧的编号版本。当您添加模型版本时,数字后缀将增加为 2..3..4,这意味着 2 是最旧的 3 次等。但当前要编辑的版本是未编号的版本。

Do not delete old model versions as users with previous db using an old model version will not be able to migrate to your latest db model with out comparing old and latest schemas.

不要删除旧模型版本,因为使用旧模型版本的先前数据库的用户将无法迁移到最新的数据库模型而不比较旧的和最新的模式。

回答by rustyshelf

Just a note for those that come across this Googling, it seems even with auto(magic) migration you still need to create a version of your original store, and a new one, and set the new one as the current version.

对于遇到此谷歌搜索的人,请注意,即使使用自动(魔术)迁移,您仍然需要创建原始商店的一个版本和一个新版本,并将新版本设置为当前版本。

回答by Thorsten Niehues

So far I only see how to avoid the error message.

到目前为止,我只看到如何避免错误消息。

But how do we fix it - in case we messed things up already??

但是我们如何修复它 - 以防我们已经把事情搞砸了??

The following solution fixed the problem but you will loose the datain the DB:

以下解决方案解决了该问题,但您将丢失数据库中的数据:

Delete / rename the sqlite fileof the deployed / installed application.
The files name an location are given directly after the error message. e.g.:

删除/重命名已部署/已安装应用程序的 sqlite 文件
文件名和位置直接在错误消息之后给出。例如:

reason=Can't find model for source store}, {
URL= "file://localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/62F342D4-F007-4F6F-96D2-68F902D3719A/Documents/Locations.sqlite";

原因=找不到源存储模型}, {
URL= "file://localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/62F342D4-F007-4F6F-96D2-68F902D3719A/文件/位置.sqlite";

回答by Sai Ramachandran

Something to keep in mind when doing a lightweight migration -

进行轻量级迁移时要记住的事情 -

If you plan to rename/modify attributes, remember to set the "Renaming ID" value in either the new or the old model. To use Apple's own example, in XCode 4.3, select paintColor in the new model > switch to the Data Model Inspector > Set the "Renaming ID" field to Color in the "Versioning" section. For me, failure to do this step led to a run time error. This same error is also covered here. As a new user, I'm not allowed to post images, so here's an imgur link(not spam, really).

如果您计划重命名/修改属性,请记住在新模型或旧模型中设置“重命名 ID”值。要使用 Apple 自己的示例,在 XCode 4.3 中,在新模型中选择 PaintColor > 切换到数据模型检查器 > 在“Versioning”部分中将“Renaming ID”字段设置为 Color。对我来说,未能执行此步骤会导致运行时错误。此处涵盖了相同的错误。作为一个新用户,我不允许发布图片,所以这里有一个imgur 链接(不是垃圾邮件,真的)。

    (Cocoa error 134140.)" UserInfo=0x622b350 {reason=Can't find or automatically infer mapping model for migration

回答by John Mead

You can also get this error when making a change to the data model and running on an installed app that has a different version of the sqlite file. In this case just delete the installed app and re-run it.

当更改数据模型并在具有不同版本的 sqlite 文件的已安装应用程序上运行时,您也可能会收到此错误。在这种情况下,只需删除已安装的应用程序并重新运行它。

回答by shawnwall

Just in case someone runs into this scenario and none of the above works... I was deleting my app from the simulator, cleaning, etc, but nothing would work. I had to go to the simulator directory and manually rm the .sqlite file to get the app working again. No clue...

以防万一有人遇到这种情况并且以上都不起作用......我正在从模拟器中删除我的应用程序,清理等,但没有任何效果。我必须转到模拟器目录并手动 rm .sqlite 文件才能使应用程序再次运行。没有线索...