希望你能提供帮助。
我有一个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
答案 0 :(得分: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。