新项目中的 CoreData
Posted
技术标签:
【中文标题】新项目中的 CoreData【英文标题】:CoreData in new project 【发布时间】:2014-05-29 11:23:08 【问题描述】:希望您能提供帮助。
我有一个 3 年前使用 CoreData 构建的 ios 应用。进行一些重大更新的机会出现了,人们认为在继续使用现有捆绑标识符的同时简单地启动一个新的 Xcode 项目更容易,这样应用程序仍然是 iTune 用户的实际更新。
我的问题是;在 Xcode 中创建一个新项目并从第一个版本手动创建模型/实体/属性的复制会阻止数据在新项目中可用吗?
我在应用程序的第一个版本中有一些快速代码,它只返回数据中的记录数(见下文),但是当在新项目中使用相同的代码时,它什么也不返回,就好像有应用程序中没有数据。 iCloud 也用于第一个版本。
我想如果我安装了应用程序的第一个版本,创建了一些记录,然后安装了新版本,数据仍然可用。
我是否误解了迁移如何与 CoreData 一起工作,我是否最好获取旧项目、重构 ARC 并手动移动新代码以便仍使用原始实体?
任何建议将不胜感激。
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *entityName = @"MyObjects";
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"row_id"
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)]];
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyObjects" withExtension:@"mom"];
NSManagedObjectModel *managedObject = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSString *iCloudEnabledAppID = @"com.xxxx.myobjects";
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObject];
NSString *dataFileName = @"MyObjects.sql";
NSString *iCloudDataDirectoryName = @"Data.nosync";
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[coordinator lock];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[coordinator unlock];
NSManagedObjectContext *moc = nil;
if (coordinator != nil)
moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator: coordinator];
NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:moc
sectionNameKeyPath:nil
cacheName:nil];
[fetchedResultsController performFetch:nil];
NSLog(@">>>>>> %@", [fetchedResultsController fetchedObjects]); // returns 2 records
【问题讨论】:
【参考方案1】:首先,我不确定您为什么用 MagicalRecord 标记此内容。您的示例代码都是原始核心数据。
其次,如果我是你,我会从旧应用程序中获取现有模型文件,并将其作为新应用程序中数据模型的第一个版本。您可以使用属性和实体等重新创建数据模型,并最终得到相同版本的哈希值,但如果您已经有了起点,则无需经历这些麻烦.只需从现有数据模型开始并继续前进。 Xcode 和 Core Data 不会将数据模型文件绑定到 Xcode 项目,并且您没有任何锁定方式。托管对象模型文件与您应用中的所有其他代码一样只是文本文件。
第三,iCloud 设置在 iOS7 中需要的代码要少得多。这很简单,因为 Core Data 团队决定负责所有设置和备用存储的繁忙工作。我建议查看 WWDC2013 的“Core Data 中的新功能”演讲。
最后,您确定您实际上已将模型复制到现有商店吗?如果您的模型与存储不兼容,您的核心数据堆栈将不会附加持久存储。也就是说,从顶层(您的 NSManagedObjectContext)看,它似乎已初始化,但附加的 NSPersistentStoreCoordinator 将没有任何存储。如果没有存储,则不会保存任何数据,也不会加载任何数据。托管对象模型版本必须与存储文件中的版本信息匹配。您可以通过以下方式自行检查:
-[NSPersistentStoreCoordinator metadataForPersistentStore:]
或
+[NSPersistentStoreCoordinator metadataForPersistentStoreOfType:URL:error:]
结合
-[NSManagedObjectModel isConfiguration:compatibleWithStoreMetadata:]
您还提到了迁移。除非您拥有多个数据模型,否则您实际上并没有迁移数据。但是,当您确实有要迁移的版本时,您还需要为轻量级迁移(自动迁移)设置迁移选项,以便在将存储附加到协调器时执行操作。我建议阅读Apple Documentation on Versioning and Migration。
【讨论】:
假设可以访问旧项目,我会添加它。人们可能能够获得在分发中使用的实际持久存储(或至少接近近似值),否则即使管道完全正确,OP 也必须重建数据。 谢谢你们。在发布这篇文章后不久,我尝试从旧应用程序中获取数据模型并将其放入新应用程序中,但运气不佳。我将检查以确保我的持久存储也已被复制。为 MagicalRecord 标签道歉。我在项目中确实有 MagicalRecord,但在尝试解决它的最后几天我已经减少了它以尝试保持代码“原始”,只是为了消除 MagicalRecord 作为原因。再次感谢。以上是关于新项目中的 CoreData的主要内容,如果未能解决你的问题,请参考以下文章