Coredata手动迁移

时间:2010-09-17 14:16:45

标签: iphone cocoa-touch core-data ios4 migration

我在iOS项目中使用Core数据。每当我修改实体属性时,我都有自动数据迁移的数据模型设置。但我最近对一些实体关系进行了一些更改,现在我的应用程序崩溃了:“无法找到源存储模型”

我意识到重置应用程序,即删除和重新安装将解决此问题,我已经有了一个实时版本,我的用户将丢失所有数据!

所以现在我正在尝试手动迁移,但iOS文档不是很有帮助。例如,我有这个代码,我在创建模型映射后运行:

NSURL *destinationStoreURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @"import.sqlite"]];

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

//initialize migration manager
NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:[[self persistentStoreCoordinator] managedObjectModel]
                                                                      destinationModel:[[self persistentStoreCoordinator] managedObjectModel]];

//perform migration     
NSError *error = nil;       
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[[self persistentStoreCoordinator] managedObjectModel]
                                                                 destinationModel:[[self persistentStoreCoordinator] managedObjectModel] error:&error];

if (mappingModel == nil) {
    NSLog(@"No Mapping model error %@, %@", error, [error userInfo]);
}

[migrationManager migrateStoreFromURL:sourceStoreURL
                                 type:NSSQLiteStoreType
                              options:nil
                     withMappingModel:mappingModel
                     toDestinationURL:destinationStoreURL
                      destinationType:NSSQLiteStoreType
                   destinationOptions:nil
                                error:&error];  

运行此代码可以正常运行并重置数据库,但是我无法找到旧数据,当我保存任何新数据时,我收到一条错误,即没有持久存储!

有没有人有任何想法?

4 个答案:

答案 0 :(得分:1)

核心数据将首先检查您的数据模型是否与当前数据存储兼容,但如果您修改了这些关系,则不会出现这种情况。您需要首先添加模型版本,可以通过选择数据模型从Xcode完成,然后从菜单中选择选项Design> Data Model> Add Model Version。您还需要设置模型的当前版本。

Apple有一些关于迁移的好资源。

答案 1 :(得分:1)

这些家伙是对的......

如果还不晚,请尝试以下操作:打开“[your database] .xcdatamodel”文件。然后(假设您使用的是Xcode),转到主菜单。选择设计>数据模型>添加模型版本。这会创建一个新文件,在我们的例子中,“[your database] 2.xcdatamodel”:

现在去设计>数据模型>设置当前版本。这样做会告诉Xcode这是您将要使用的数据库架构。现在进行所需的任何数据库架构更改。现在可能是在直接影响数据库模式更改的情况下进行任何代码更改的好时机。

现在编译你的程序。这次它应该加载。

我遇到了同样的麻烦。这是我第一次真正阅读iPhone开发文档。我必须要特别注意。现在我已经准备好了。我实际选择了轻量级迁移。这段代码是直接从Apple的一个(或几个)示例程序中劫持的(这些程序通常有错误,所以你会知道...: - /)

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 
 if (persistentStoreCoordinator != nil) {
    return persistentStoreCoordinator;
 }

 NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
      stringByAppendingPathComponent:DATABASENAME]];
 NSError *error;
 persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:      
  [self managedObjectModel]];

 // Allow inferred migration from the original version of the application.
 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithBool:YES], 
        NSMigratePersistentStoresAutomaticallyOption,
        [NSNumber numberWithBool:YES], 
         NSInferMappingModelAutomaticallyOption, nil];

 //ATTENTION: YOU WERE CRASHING HERE...
 if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
 configuration:nil URL:storeUrl options:options error:&error]) {
       // Handle the error.
      NSLog(@"WTF??? FAILED to create automatic lightweight migration. Error[%@]", error);
 }    

答案 2 :(得分:0)

您是否从设计菜单中设置了当前版本?假设选项NSMigratePersistentStoresAutomaticallyOption和NSInferMappingModelAutomaticallyOption设置为YES,则自动迁移应该在此之后工作。

答案 3 :(得分:0)

轻量级迁移:对于那些即使遵循上述步骤也失败的人!

只需确保将DATABASE.sqlite重命名为DATABASE.xcdatamodeld,并将它们放在Documents目录下的同一位置:)祝你好运