在iOS13中使用NSPersistentCloudKitContainer进行CloudKit同步

时间:2019-10-01 07:21:49

标签: core-data cloudkit ios13

我正在为我的Core Data应用程序使用NSPersistentCloudKitContainer。在测试过程中,我检查了设备上所做的更改是否能在一秒钟内同步到CloudKit。

但是,当我在设备上禁用iCloud然后立即重新启用时,设备上的所有数据都消失了。我检查私有数据库中的数据是否仍存在于CloudKit上。将CloudKit上的数据同步回我的设备花了超过1天的时间。

这将在用户更换设备并首先看到他们的数据消失时引起混乱。问题:如何控制CloudKit上的数据同步到我的设备的速度有多快?

1 个答案:

答案 0 :(得分:3)

令人沮丧的是,我认为这是“正常”的行为,特别是对于具有大量要同步的关系的大型数据库-无法查看进度(向用户显示),也无法加快进度。< / p>

NSPersistentCloudKitContainer似乎将每个关系都视为一个单独的CKRecord,并且同步仍然受到相同的限制(即一次不超过400个“请求”),您经常会看到控制台中出现这些.limitExceeded错误,但几乎没有其他信息(即,是否/何时重试?)。

我发现此结果导致数据库需要花费来完全同步,与此同时,数据看起来混乱且不完整。我有成千上万的一对多关系,当用户从外部文件恢复数据库时,所有这些CKRecord都需要重新创建。

我在这里主要担心的是,无法查询NSPersistentCloudKitContainer是否有待处理的请求,尚未同步的请求数等等,因此您可以将其转发给用户用户界面,这样他们就不会继续删除和恢复,认为它是“失败的”。

一种解决方法是在关闭同步时删除本地数据-并可能在打开时将其全部重新同步-可以在关闭时使用NSPersistentContainer,以及NSPersistentCloudKitContainer处于启用状态。

NSPersistentCloudKitContainerNSPersistentContainer的子类。

我目前正在我的自定义PersistenceService类的应用程序中执行此操作:

static var useCloudSync = UserDefaults.standard.bool(forKey: "useCloudSync")
static var persistentContainer:  NSPersistentContainer  = {
    let container: NSPersistentContainer?
    if useCloudSync {
        container = NSPersistentCloudKitContainer(name: "MyApp")
    } else {
        container = NSPersistentContainer(name: "MyApp")
        let description = container!.persistentStoreDescriptions.first
        description?.setOption(true as NSNumber,
                               forKey: NSPersistentHistoryTrackingKey)

    }
    container!.loadPersistentStores(completionHandler: { (storeDescription, error) in
    if let error = error as NSError? {
        fatalError("Unresolved error \(error), \(error.userInfo)")
    }
    })
    return container!
}()

这至少会导致在您的应用程序中关闭iCloud时未更改本地数据,并且不需要在重新打开后重新同步所有内容。

我认为您还可以查询iOS,以查看用户是否已在系统设置中关闭了iCloud,并在NSPersistentCloudKitContainer删除所有本地数据之前在这两个之间切换。

编辑:添加了NSPersistentHistoryTrackingKey,与没有添加时一样,从NSPersistentContainer切换回NSPersistentCloudKitContainer失败。

它在我的应用中正常运行。当用户在我的应用程序中重新启用iCloud同步(并从NSPersistentContainer切换到NSPersistentCloudKitContainer)时,它会同步自上次同步以来添加/更改的所有内容,这正是我想要的!