核心数据(iPhone)的“自动轻量级移植”
我想使我的应用程序能够进行自动轻量级迁移,当我添加新的属性到我的核心数据模型。
在苹果的指南中,这是我能find的唯一信息:
自动轻量级迁移
要请求自动轻量级迁移,请在您通过addPersistentStoreWithType传递的选项字典中设置适当的标志:configuration:URL:options:error :. 您需要将对应于NSMigratePersistentStoresAutomaticallyOption和NSInferMappingModelAutomaticallyOption键的值设置为YES:
NSError *error; NSURL *storeURL = <#The URL of a persistent store#>; NSPersistentStoreCoordinator *psc = <#The coordinator#>; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; if (![psc addPersistentStoreWithType:<#Store type#> configuration:<#Configuration or nil#> URL:storeURL options:options error:&error]) { // Handle the error. }
我的NSPersistentStoreCoordinator
是这样初始化的:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FC.sqlite"]]; NSError *error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return persistentStoreCoordinator; }
我无法查看在哪里以及如何添加Apple代码以使自动轻量级迁移工作?
这是我做自动轻量级移植(来源: http : //brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/ )
1.在应用程序委托中设置自动迁移的持久存储选项。
将您的persistentStoreCoordinator创build更改为此(replaceYOURDB):
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]]; // handle db upgrade NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; NSError *error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { // Handle error } return persistentStoreCoordinator; }
2.版本您的数据模型和编辑新的文件。
select您的xcdatamodel文件devise – >数据模型 – >添加模型版本(展开您的xcdatamodeld项目)select“2”(或更高版本)文件,devise – >数据模型 – >设置当前版本(编辑此版本)
3.在应用程序委托中指定momd资源。
将您的managedObjectModel实现更改为此(replaceYOURDB)
- (NSManagedObjectModel *)managedObjectModel { if (managedObjectModel != nil) { return managedObjectModel; } NSString *path = [[NSBundle mainBundle] pathForResource:@"YOURDB" ofType:@"momd"]; NSURL *momURL = [NSURL fileURLWithPath:path]; managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; return managedObjectModel; }
起初,上面的解决scheme不适合我。 返回的managedObjectModel是0x0。 我想这是因为我重命名了不同模型文件的文件名。 如果你按照上面的说明,那么这一切都有效。
但是,如果您更改模型文件名,那么您可以手动select“当前”模型文件:假设您的原始模型文件是MYMODEL.xcdatamodel,然后执行上面的添加模型步骤,将会变成一个目录MY.xcdatamodeld,并在其下面MYMODEL.xcdatamodel和MYMODEL 2.xcdatamodel将新的模型文件重新命名为任何你想要的,例如让我们说你把空间去掉了MYMODEL2.xcdatamodel并编辑它的内容。 现在在上面的代码中做
NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
我认为这增加了最后的答案。
我发现bundle资源和.sqlite名字的用法一开始真的让人困惑。 软件包资源名称是否随版本更改而变化? .sqlite名称是否更改? 我现在已经进行了迁移工作,了解到bundle模型名称是指包含所有模型的XCode中的目录/文件夹的名称,而不是该目录中模型版本的名称。
当你给modelResource名称:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"]; NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
该modelResource名称是Xcode中模型的目录/文件夹。
当你这样做时:
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:storeFileName]; NSError *error = nil; if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { // handle error }
storeFileName是Documents文件夹/目录中的.sqlite文件的名称( 不在包中)。
另外,从一个模型版本迁移到另一个模型版本时,默认情况下.sqlite文件名保持不变。
奥斯卡,为了回应你的问题,我最初find了同样的事情。 我build议删除并重新添加新的.xcdatamodeld文件到您的项目,然后重build。 希望有所帮助!
Swift 3解决scheme
1.在应用程序委托中设置自动迁移的持久存储选项。
将您的persistentStoreCoordinator创build更改为此(replaceSingleViewCoreData.sqlite):
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite") let options = [ NSMigratePersistentStoresAutomaticallyOption : Int(true), NSInferMappingModelAutomaticallyOption : Int(true) ] do { try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options) } catch { print(error) } return coordinator }()
2.版本您的数据模型和编辑新的文件。
select您的xcdatamodel文件编辑器>添加模型版本 – 为您的新模型添加一个名称