首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CloudKit同步在iOS13中使用NSPersistentCloudKitContainer

CloudKit同步在iOS13中使用NSPersistentCloudKitContainer
EN

Stack Overflow用户
提问于 2019-10-01 07:21:49
回答 1查看 3K关注 0票数 10

我使用NSPersistentCloudKitContainer作为我的核心数据应用程序。在测试期间,我检查了设备上所做的更改是否在秒内同步到CloudKit。

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

当用户改变设备时,看到他们的数据一开始就消失了,这将给他们造成混乱。问:如何控制CloudKit上的数据同步回我的设备的速度?

EN

回答 1

Stack Overflow用户

发布于 2019-10-20 02:01:06

令人沮丧的是,我认为这是“正常的”行为,特别是在拥有大量需要同步的关系的大型数据库中--没有办法看到进展(向用户展示),也无法加快进度。

NSPersistentCloudKitContainer似乎将每一种关系视为一个单独的CKRecord,而同步仍然受到相同的限制(即。一次不超过400个“请求”),您通常会在控制台中看到这些.limitExceeded错误,但是很少有其他信息(例如。如果/什么时候会重试?)

我在数据库中发现这个结果需要几天的时间才能完全同步,同时数据看起来很混乱而且不完整。我有数以千计的多到多的关系,当用户从外部文件恢复他们的数据库时,所有这些CKRecords都需要重新创建。

我在这里主要关心的是,没有办法查询NSPersistentCloudKitContainer 是否有挂起的请求,还有多少尚未同步,这样您就可以将其转发给UI中的用户,这样他们就不会一直删除和恢复“失败”的信息。

在关闭同步时删除本地数据的一种方法是在关闭时使用NSPersistentContainer,并在打开时使用NSPersistentCloudKitContainer

NSPersistentCloudKitContainerNSPersistentContainer的子类。

我目前正在我的自定义PersistenceService类中的应用程序中这样做:

代码语言:javascript
运行
复制
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!
}()

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

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

NSPersistentHistoryTrackingKey编辑:在没有它的情况下添加,从 NSPersistentCloudKitContainer 切换回 NSPersistentContainer 失败。

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

编辑2:下面是上述的更好实现

本质上,无论用户是否同步到iCloud,只需更改容器上的.options以使用NSPersistentCloudKitContainerOptions(containerIdentifier:)nil。似乎根本不需要在NSPersistentCloudKitContainerNSPersistentContainer之间切换。

代码语言:javascript
运行
复制
static var synciCloudData = {
    return defaults.bool(forKey: Settings.synciCloudData.key)
}()

static var persistentContainer:  NSPersistentContainer  = {
    let container = NSPersistentCloudKitContainer(name: "AppName")
    
    guard let description = container.persistentStoreDescriptions.first else {
        fatalError("Could not retrieve a persistent store description.")
    }
    
    description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
    
    if synciCloudData {
        let cloudKitContainerIdentifier = "iCloud.com.yourID.AppName"
        let options = NSPersistentCloudKitContainerOptions(containerIdentifier: cloudKitContainerIdentifier)
        
        description.cloudKitContainerOptions = options
    } else {
        description.cloudKitContainerOptions = nil
    }
            
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    
    return container
}()

最后,您可以看到iCloud同步的状态,尽管很粗略(即。您不能只看到任何东西都是“同步”的,只有同步正在挂起/正在进行,以及它是成功的还是失败的。尽管如此,对于我的应用程序中的用例来说,这已经足够了。

请参见用户ggruen对下面文章的答复:NSPersistentCloudKitContainer: How to check if data is synced to CloudKit

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58179862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档