我继承了一个需要经历重大变革的iOS应用。在其当前形式中,它使用单个UIManagedDocument(未与iCloud同步,但仅用于避免Core Data样板)来存储用户数据。我需要对数据模型进行重大更改,并且我希望切换到正常的Core Data堆栈。现有的代码库也很不可用,所以我决定创建一个新项目但是具有相同的应用程序ID,因此它可以作为更新发布。
我不确定如何导入现有用户'数据到新数据模型。
当前模型有3个主要实体,我每个只需要2个属性(旧数据的其余部分可以扔掉)。我已经创建了我的新数据模型,然后我复制了以前项目中的所有旧模型文件以及旧数据模型。
然后我写了一个导入类:
-(BOOL)isImportNeeded
{
return [[NSFileManager defaultManager] fileExistsAtPath:[[self URLToOldModel] path]];
}
-(NSURL*)URLToOldModel
{
NSURL* URL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
return [URL URLByAppendingPathComponent:@"Data"];
}
-(UIManagedDocument*)managedDocumentAtPath:(NSString*)path
{
return [[UIManagedDocument alloc] initWithFileURL:[self URLToOldModel]];
}
-(void)performWithDocument:(void (^)(void))onDocumentReady
{
if (self.managedDoc.documentState == UIDocumentStateClosed) {
// I put this code here for debug purposes
NSError* e = nil;
if (![self.managedDoc readFromURL:self.managedDoc.fileURL error:&e]) {
NSLog(@"Couldn't read UIManagedDocument: %@", [e localizedDescription]);
}
// [self.managedDoc openWithCompletionHandler:^(BOOL success){
// if (success)
// onDocumentReady();
// else
// NSLog(@"Could not open document");
// }];
}
else if (self.managedDoc.documentState == UIDocumentStateNormal)
{
onDocumentReady();
}
}
-(void)import
{
self.managedDoc = [self managedDocumentAtPath:[[self URLToOldModel] path]];
self.sourceManagedObjectContext = self.managedDoc.managedObjectContext;
[self performWithDocument:^{ ... }];
}
NSLog
打印出以下内容:Couldn't read UIManagedDocument: The operation couldn’t be completed. (Cocoa error 134100.)
在错误的userInfo
字典中钻取更多内容,我将此作为错误原因:"用于打开商店的模型与用于创建商店的模型不兼容。
我已确保将旧数据模型添加到项目中并且位于"编译源"建设阶段。
我学到了更多关于UIManagedDocument的知识,并意识到当它被初始化时,它会自动创建bundle中所有数据模型的联合,并且通过继承UIManagedDocument并覆盖managedObjectModel
访问器来阻止它。我这样做了,只需使用以下方法创建一个子类:
-(NSManagedObjectModel*)managedObjectModel
{
NSString* modelPath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"momd"];
modelPath = [modelPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL* modelURL = [NSURL URLWithString:modelPath];
return [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
}
但是,我仍然得到同样的错误。
答案 0 :(得分:0)
我的一位朋友提出了这个问题,我曾在我曾经使用的每个核心数据应用程序中使用过 - 不知道它是如何逃过我的:
self.managedDoc.persistentStoreOptions = @{NSIgnorePersistentStoreVersioningOption: @YES,
NSMigratePersistentStoresAutomaticallyOption: @YES,
NSInferMappingModelAutomaticallyOption: @YES};
这样做了。