Core Data(iPhone)实现“自动轻量级迁移”
Posted
技术标签:
【中文标题】Core Data(iPhone)实现“自动轻量级迁移”【英文标题】:Implementation of "Automatic Lightweight Migration" for Core Data (iPhone) 【发布时间】:2011-01-19 14:15:09 【问题描述】:我想让我的应用在添加时能够进行自动轻量级迁移 我的核心数据模型的新属性。
在 Apple 的指南中,这是我能找到的关于该主题的唯一信息:
自动轻量级迁移
请求自动轻量化 迁移,您设置适当的标志 在您传入的选项字典中 addPersistentStoreWithType:configuration:URL:options:error:。 您需要设置相应的值 对双方 NSMigratePersistentStoresAutomatically 选项 和 NSInferMappingModelAutomaticallyOption 是的关键:
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 代码以使自动轻量级迁移正常工作?
【问题讨论】:
Swift 4 版本点击此链接 - ***.com/questions/51519516/… 【参考方案1】:这就是我所做的自动轻量级迁移(来源:http://brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/)
1。在应用委托中设置用于自动迁移的 Persistent Store 选项。
将您的 persistentStoreCoordinator 创建更改为此(替换 YOURDB):
- (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。版本化您的数据模型并编辑新文件。
选择您的 xcdatamodel 文件 设计 -> 数据模型 -> 添加模型版本(展开您的 xcdatamodeld 项) 选择“2”(或更高版本)文件,Design -> Data Model -> Set Current Version(编辑此版本)
3。在应用委托中指定 momd 资源。
将您的 managedObjectModel 实现更改为此(替换 YOURDB)
- (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;
【讨论】:
嗨,Willi,非常感谢您抽出宝贵时间填补所有空白:) 非常有帮助!非常感谢! 您可以链接到源:brainwashinc.wordpress.com/2010/01/18/… 第 2 步在 XCode 4.3 中略有不同(至少):要设置当前模式版本,您必须首先选择看起来像包含“旧”和“新”版本的文件夹的数据模型你的数据模型。您将在项目导航器中看到它。选择此“文件夹”,在右侧的属性检查器中,您将找到“版本化核心数据模型”——从那里的下拉框中选择所需的一个。 Step2 XCODE 4.6 更新:标记.xcdatamodeld->Editor->添加模型版本【参考方案2】:起初,上述解决方案对我不起作用。返回的 managedObjectModel 为 0x0。 我认为这是因为我重命名了不同模型文件的文件名。 如果您按照上面的说明进行操作,那么一切正常。
但是,如果您确实更改了模型文件名,那么您可以手动选择“当前”模型文件: 假设您的原始模型文件是 MYMODEL.xcdatamodel 完成上面的添加模型步骤后,这变成了一个目录 MY.xcdatamodeld 在它下面你有 MYMODEL.xcdatamodel 和 MYMODEL 2.xcdatamodel 将新模型文件重命名为您想要的任何名称,例如,假设您删除了 MYMODEL2.xcdatamodel 的空间并编辑其内容。 现在在上面的代码中做
NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
【讨论】:
你好 udibr。谢谢,我确实遇到了这个问题:)我也遇到了试图更改我的 app.sql 文件名称的问题,当处理一个已经在运行的项目时,这也会导致一切崩溃。在你写的时候,如果你按照这封信的指示,一切都会很好,所以投票给威利:) 每当我尝试使用上述代码时...我收到此错误... *** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'*** -[NSURL initFileURLWithPath: ]: nil 字符串参数'有什么想法吗?【参考方案3】:我认为这增加了最后一个答案。
一开始我发现捆绑资源和 .sqlite 名称的使用确实令人困惑。捆绑资源名称是否会随着版本的变化而变化? .sqlite 名称会改变吗?我现在已经开始进行迁移,并且了解到捆绑模型名称是指 XCode 中包含所有模型的目录/文件夹的名称,而不是该目录中模型版本的名称。
当您将模型资源名称指定给:
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 文件名保持不变。
【讨论】:
【参考方案4】:Oscar,针对您的问题,我最初发现了同样的问题。我建议删除新的 .xcdatamodeld 文件并将其重新添加到您的项目中,然后重新构建。希望有帮助!
【讨论】:
【参考方案5】:Swift 3 解决方案
1.在应用委托中设置用于自动迁移的 Persistent Store 选项。
将您的 persistentStoreCoordinator 创建更改为此(替换 SingleViewCoreData.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。版本化您的数据模型并编辑新文件。
选择您的 xcdatamodel 文件编辑器>添加模型版本 - 为您的新模型添加名称
【讨论】:
以上是关于Core Data(iPhone)实现“自动轻量级迁移”的主要内容,如果未能解决你的问题,请参考以下文章