将部分Core Data保存到云端

时间:2014-12-01 16:00:00

标签: ios core-data icloud

在iOS 7上工作时,我必须使用具有多个实体的Core Data调试应用程序。首先,我要求添加iCloud(而不是云套件)来保存所有数据。但随后,客户意识到他只想保存一些实体,而不是全部保存到云中。

有可能吗?我需要使用几个NSPersistentStoreCoordinator吗? (该应用程序已经使用了几个NSManagedObjectContext,每个实体一个)。或者,当我收到通知时,我可以做点什么:

NSPersistentStoreDidImportUbiquitousContentChangesNotification

并手动执行合并但我真的不知道如何。

感谢您的帮助。


感谢Tom Harrington,我创建了2个配置:CloudConfiguration和LocalConfiguration,我在每个中添加了一些实体(这个link也帮助了我。)

然后,我在协调器中添加持久存储:

    // Configure persistentStoreCoordinator
    NSError* error1 = nil;
    NSString *cloudConfiguration = @"CloudConfiguration";
    NSPersistentStore *store1 = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                                         configuration:@"CloudConfiguration"
                                                                                   URL:[self storeURLForConfiguration:cloudConfiguration]
                                                                               options:@{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" }
                                                                                 error:&error1];
    if (error1) {
        NSLog(@"Error: %@ \n Description : %@ \nUser info : %@", error1, error1.description, error1.userInfo);
    }
    NSLog(@"*************** cloud store url ************** : %@", store1.URL);

    NSError* error2 = nil;
    NSString *localConfiguration = @"LocalConfiguration";
    NSPersistentStore *localStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                      configuration:localConfiguration
                                                                URL:[self storeURLForConfiguration:localConfiguration]
                                                            options:nil
                                                              error:&error2];
    if (error2) {
        NSLog(@"Error: %@ \n Description : %@ \nUser info : %@", error2, error2.description, error2.userInfo);
    }

    NSLog(@"*************** local store url ************** : %@", localStore.URL);

我的所有实体只进入一个商店(云或本地)。不同商店的实体没有任何关系,我只有一个模型。

所以我走了,我第一次启动我的应用程序似乎配置得很好。但是当我在删除应用程序后尝试使用其他设备或同一设备时,我遇到了崩溃:获取后:使用本地存储:0。

以下是崩溃日志:

[_PFUbiquityRecordImportOperation main](734): CoreData: Ubiquity:  Error importing transaction log: <PFUbiquityTransactionLog: 0x16ed7f50>
transactionLogLocation: <PFUbiquityLocation: 0x16ed7ee0>: /var/mobile/Library/Mobile Documents/6ULEJ9RYTQ~fr~company~iCloudTestApp/CoreData/iCloudStore/mobile~E722813A-96E8-4E11-8DDE-56FF3837DEBD/iCloudStore/EU31J4aJIvvEyVMcWWYs1qgVajMk4_4fQxw1oe_Q0i0=/4C6B58B3-6C8D-4393-9B1E-8E48C7352091.1.cdt
transactionNumber: 1, exception: Invalid parameter value (bad entity)
User Info: (null)
2014-12-02 12:35:34.837 iCloudTestApp[1421:3b0b] -[_PFUbiquityRecordsImporter discoverAndImportAllAvailableLogs:error:](727): CoreData: Ubiquity:  Exception while scanning for logs to import: Invalid parameter value (bad entity)
userInfo: (null)

这对我来说听起来很奇怪,因为它发生在合并之前。当然,在使用这两种配置进行测试之前,我会删除云中的所有数据。如果您有任何想法......

1 个答案:

答案 0 :(得分:4)

不是多个持久性存储协调器,而是多个持久性存储文件。您可以多次调用addPersistentStoreWithType:configuration:URL:options:error:将多个持久性存储添加到同一个协调器。您不必每次都使用相同的选项,因此您可以将iCloud选项用于一个商店文件,但将其留给另一个商店文件。

但你需要注意以下几点:

  1. 您无法在不同的持久性存储文件中创建对象之间的关系。如果这是一个问题,请查看已获取的属性。它们是使用您提供的谓词透明地获取对象的属性。他们的工作方式有点像单向关系。

  2. 您需要某种方式告诉Core Data哪个存储文件用于新对象。有几种方法可以做到这一点:

    • 如果您的某些实体可以进入任何持久性商店,则每次创建新实例时都需要使用[NSManagedObjectContext assignObject:toPersistentStore:]
    • 对于始终位于同一商店文件中的实体,请查看&#34;配置&#34;为您的模型文件。这使您可以创建仅包含某些实体的模型的命名子集。添加持久性存储文件时使用配置名称。然后,这些实体的所有新实例将自动转到正确的文件。
  3. 另外,根据更新的问题:

    如果已经拥有您需要使用的iCloud数据,则无法切换到使用配置。现有的iCloud事务日志可能包含对不在新的仅iCloud配置中的实体的引用。当它尝试导入该数据时,它将失败,并且您将收到类似您所看到的错误。

    如果此应用仍处于开发阶段,我只想删除所有现有的iCloud数据并继续配置。如果需要保留现有的iCloud数据,则必须确保当前iCloud数据中的所有实体仍然可用。这很可能意味着您必须在没有配置的情况下进行操作,而是将对象分配给代码中的一个商店或另一个商店。