新项目中的CoreData

时间:2014-05-29 11:23:09

标签: ios objective-c core-data

希望你能提供帮助。

我有一个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 个答案:

答案 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