Ios 如何将初始数据植入核心数据&x2B;iCloud?

Ios 如何将初始数据植入核心数据&x2B;iCloud?,ios,iphone,core-data,icloud,Ios,Iphone,Core Data,Icloud,我正在开发一款使用核心数据和iCloud的新应用程序。我正在关注iCloudCoreDataStack演示和iCloud设计指南。 到目前为止,设备之间的同步工作正常,但我还没有弄清楚如何在用户的第一台设备上首次使用应用程序时播种少量数据,如果应用程序在第二台设备上使用,则跳过播种(因为它应该从iCloud下载) 这应该很简单,只需询问iCloud容器是否有任何数据。下载数据(如果存在),或者创建新数据(如果不存在)。 但我找不到这样做的方法:-( 我可以想出三种方法来解决这个问题: 使用mig

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

这应该很简单,只需询问iCloud容器是否有任何数据。下载数据(如果存在),或者创建新数据(如果不存在)。 但我找不到这样做的方法:-(

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

  • 使用migratePersistentStore:toURL:options:withType:error: 我有一个非常小的数据量,所以在这种情况下,这感觉像是矫枉过正

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

  • 使用sentinel文件具有与#2相同的效果(我不确定如何实现)

  • 该应用程序仅适用于iOS 7且是新的,因此无需迁移旧用户数据

    我发现的所有相关教程和书籍似乎都在使用iOS 7之前的超级复杂方式(例如使用后备存储),而这在iOS 7上是不必要的

    要么我遗漏了什么(通常情况下),要么这比应该的更复杂。
    我非常感谢您的建议和指点。

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

    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];
    
    这就是说,这是可能的,尽管在核心数据初始导入完成的基础上播种是不明智的

    您需要等待NSPersistentStoreCoordinatorsStoresIDChangeNotification,并将NSPersistentStoreUbiquiousTransitionTypeKey设置为NSPersistentStoreUbiquiousTransitionTypeInitialImportCompleted

    如果存储中没有数据,则可以在该点为初始数据集设定种子

    但是,重要的是要认识到,多个设备可以在不导入种子数据的情况下接收初始导入通知,从而再次对其进行种子化。这是无法避免的


    在您的应用程序中提供第二个持久性存储,作为种子数据

    正如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存储中

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

    尝试这种方法:

    在创建本地存储之前,通过查找iCloud/CoreData目录中是否存在名为“NSPersistentStoreUbiquitousNameKey”的目录,检查是否已经在iCloud中创建了本地存储

    如果存在,则意味着其他设备已经创建了存储并在iCloud中共享,因此在设备上创建本地存储时,不要添加种子数据,因为这将在iCloud中已经存在

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

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

    • 用户正在没有iCloud的设备上运行应用程序 已启用-如果用户选择现在从此服务器与iCloud同步 您必须处理由于尝试合并而产生的问题 来自此设备的数据已在iCloud中。请再次 可以检查iCloud中是否存在数据,然后询问用户 是否要尝试合并设备中的数据,或者 要用iCloud中的数据替换数据

    • 用户正在未连接到的设备上运行应用程序 网络——而且还没有从iCloud同步任何数据 iCloud中没有文件。然后应用程序将创建种子 数据,当它获得网络连接时,核心数据将合并 数据-您的应用程序可能必须处理随之而来的问题


    对于这些场景,您可能需要尝试用户教育。

    但当应用程序在第二台设备上使用时,如何避免使用第二个永久存储?(即,数据应该从iCloud下载)。正如他所说,不要为数据设定种子,将种子数据作为第二个只读持久存储添加到
    NSPersistentStoreCoordinator
    。这将在以后需要“更新”种子数据时为您省去痛苦。我认为写时复制在这里很有效。当他们修改或使用默认值(银行帐户、类别)时将其复制到iCloud应用商店。如果他们只是浏览,则无需写入iCloud。
    nsPersistentStoreUbiquiousTransitionTypeKey
    设置为
    nsPersistentStoreUbiquiousTransitionTypeInitialImportCompleted
    是否有效?尝试获取
    NSPersistentStoreUbiqui