2010-09-17 47 views
2

我在iOS项目中使用Core数据。无论何时修改实体属性,我都有自动数据迁移的数据模型设置。但我最近做了一些实体关系的一些变化,现在我的应用程序崩溃:“无法找到源存储模型”Coredata手动移植

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

因此,现在我正在尝试手动迁移,但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]; 

运行这段代码的工作和重置数据库,但我不能找到我的旧数据,当我保存任何新的数据,我得到没有持久存储的错误!

有没有人有任何想法?

+0

夸,我也同样的问题,但我解决不了。这篇文章正是我发生的事情。 – Xeieshan 2014-03-06 06:37:05

回答

1

的人是正确的...

如果它不是为时已晚,试试这个:打开你的“[数据库] .xcdatamodel”文件。然后(假设你正在使用Xcode),进入你的主菜单。选择设计>数据模型>添加模型版本。这将创建一个新文件,在我们的例子中,“[你的数据库] 2.xcdatamodel”:

现在转到设计>数据模型>设置当前版本。这样做会告诉Xcode,这是数据库架构可以使用。现在,让你想要的任何数据库架构更改。现在可能是一个好时机作出任何代码更改您的数据库架构的变化已直接影响。

现在编译程序。这一次,它应该加载。

我遇到了同样的麻烦,这是我第一次真正阅读iPhone开发文档,我必须真正关注,现在我全部设置好了,实际上我选择了轻量级迁移,这个代码是劫持d直接从苹果的示例程序一个(或几个)(通常都有漏洞,只是让你知道...: - /)

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

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

+0

自动迁移不起作用,因为我更改了妈妈文件中的关系。所以苹果文档建议我进行手动迁移。所以我创建了一个映射模型,比较了源和目标实体。删除不匹配的属性,然后添加上面的手动迁移代码(在注释掉轻量级迁移后)。这给我一个新的数据库。所以现在我找不到旧的数据库! – Kwame 2010-09-18 15:13:31

+0

我想我错误地设置了映射管理器和迁移管理器。请看看上面的代码,看看你的想法。我不确定要使用什么作为源模型和目标模型。也许问题在于我对两者都使用相同的模型!但是目的地模式是什么? – Kwame 2010-09-18 15:23:49

1

核心数据将首先检查您的数据模型是否与当前数据存储兼容,但如果您修改了关系,则不会是这种情况。您需要首先添加一个模型版本,可以从Xcode中选择数据模型,然后从菜单中选择设计>数据模型>添加模型版本。您还需要设置模型的当前版本。

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

+0

谢谢。我认为你所描述的是自动轻量级迁移,我已经尝试过了。它通常会给出一个错误:reason =“无法找到源存储模型”;所以这导致我尝试手动迁移。 – Kwame 2010-09-18 15:08:52

0

轻量级迁移:对于那些谁,即使按照上述失败后脚步!

只要确保重命名DATABASE.sqlite一样DATABASE.xcdatamodeld,并把他们都在同一个位置是Documents目录下:)好运气