如何将初始数据播种到Core Data + iCloud?

时间:2014-01-08 19:56:55

标签: ios iphone core-data icloud

我正在开发一款使用Core Data和iCloud的新应用。我正在关注iCloudCoreDataStack演示和iCloud设计指南。 到目前为止,设备之间的同步运行良好,但我还没有弄清楚如何在用户的第一台设备上使用应用程序时播种少量数据,如果应用程序在第二台设备上使用,则跳过播种(因为它应该从iCloud下载)。

这应该很简单,只要询问iCloud Container是否有任何数据。下载数据(如果存在)或创建新数据(如果不存在)。 但我找不到办法做到这一点: - (

我可以想出三种方法来解决这个问题:

  1. 使用migratePersistentStore:toURL:options:withType:error:  我的数据非常少,所以对于这种情况,这感觉就像是矫枉过正

  2. 在NSUbiquitousKeyValueStore上存储一个值,以标记是否已进行初始同步  我尝试使用NSUbiquitousKeyValueStore,但有时需要很长时间才能获得该值  UbiquitousKeyValueStore,即使不需要也会创建种子数据,导致重复。

  3. 使用sentinel文件与#2具有相同的效果(我不知道如何实现)

  4. 该应用仅适用于iOS 7,因此不需要迁移旧的用户数据。

    我发现的每一个相关教程和书籍似乎都使用iOS7之前的超级复杂的处理方式(例如使用后备存储),这在iOS 7中是不必要的。

    要么我缺少某些东西(通常是这种情况),要么这比它应该更复杂。 我感谢任何建议和指示。

2 个答案:

答案 0 :(得分:7)

使用初始数据集种子分布式数据存储区永远不是一个好主意。通常,这些初始数据可以打包到随应用程序提供的存储文件中,并作为第二个持久存储添加到应用程序的托管对象上下文使用的协调器中。

尽管如此,基于Core Data初始导入的完成,种子可能是不明智的。

您需要等待NSPersistentStoreCoordinatorStoresDidChangeNotification,并将 NSPersistentStoreUbiquitousTransitionTypeKey 设置为 NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted

如果商店中没有数据,您可以在该点播种初始数据集。

然而,重要的是要意识到多个设备可以在不导入种子数据的情况下接收初始导入通知,从而再次播种。没有办法避免这种情况。


关于在您的应用程序中运送第二个持久存储的问题,以作为种子数据。

这是在Marcus通过将其作为只读存储添加到应用程序的托管对象上下文正在使用的持久性存储协调器时指出的。

NSDictionary *options = @{ NSReadOnlyPersistentStoreOption: @YES };
[_psc addPersistentStoreWithType:NSSQLiteStoreType
                   configuration:nil
                             URL:seedStoreURL
                         options:options
                           error:&localError];

NSDictionary *iCloudOptions = @{ NSPersistentStoreUbiquitousContentNameKey: @"storeName" };
[_psc addPersistentStoreWithType:NSSQLiteStoreType
                   configuration:nil
                             URL:iCloudStoreURL
                         options:iCloudOptions
                           error:&localError];

_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[appMOC setPersistentStoreCoordinator:_psc];

这样,您的应用程序的托管对象上下文可以访问来自两个存储的数据,并将从获取请求中获取这两个集。托管对象上下文也足够智能,可以自动将新对象插入到正确的存储中(因为其中一个是只读的)。

唯一的技巧是,如果您希望用户能够从种子库修改数据,则需要将这些对象移动到iCloud存储。

这比尝试迁移批量数据集更容易,因为理想情况下,您的用户一次只能使用一台设备。在发生冲突的情况下,您最多只需要解决一些重复记录,而不是尝试检测整个数据集中的重复记录。

答案 1 :(得分:2)

尝试这种方法:

在创建本地商店之前,通过查找iCloud / CoreData目录中是否存在具有“NSPersistentStoreUbiquitousNameKey”名称的目录,检查是否已在iCloud中创建了一个。

如果存在,那么这意味着其他设备已经创建了一个商店并在iCloud中共享它,因此在设备上创建本地商店时不会添加种子数据,因为这已经存在于iCloud中。

如果不存在,则其他设备尚未在iCloud中共享该存储,因此您可以创建种子数据并同步到iCloud。

请注意,以下情况不适用于:

  • 用户正在没有iCloud的设备上运行该应用 启用 - 如果用户现在选择与iCloud同步 您将不得不处理因尝试合并而产生的问题 此设备中的数据已包含在iCloud中的数据。再一次,你 可以检查iCloud中是否存在数据,然后询问用户 他们是否想尝试合并设备中的数据或是否 想要用iCloud中的数据替换数据。

  • 用户正在未连接到的设备上运行该应用    网络 - 并没有从iCloud同步的任何数据,所以认为    iCloud中已有文件。该应用程序将创建种子    数据以及何时获得网络连接Core Data将合并    数据 - 你的app可能不得不处理随之而来的问题。

对于这些情况,您可能需要尝试用户培训。