【问题标题】:Synchronising old data with NSPersistentCloudKitContainer使用 NSPersistentCloudKitContainer 同步旧数据
【发布时间】:2019-07-03 18:10:27
【问题描述】:

我正在使用NSPersistentCloudKitContainer 在使用 CloudKit 的不同设备之间同步数据。它适用于新项目,但是当我将它与旧项目一起使用时,使用 NSPersistentContainer 添加的旧数据不会同步。

我想要实现的是在将NSPersistentContainer更改为NSPersistentCloudKitContainer后添加的旧数据同步。有可能吗?

【问题讨论】:

  • 因为我们现在处于 beta 5,并且仍然不会同步旧数据,我想知道这是否是设计使然。也许可能有一种同步方式,通过重新保存原始数据,同时控制我的 NSPersistentCloudKitContainer。你自己有没有更进一步?
  • 确实可能是设计使然,在 Beta 版的发行说明中没有关于此问题的内容。我现在发现的唯一方法是更改​​原始数据中的某些内容并将其保存。
  • 我真的希望我们能够同步现有数据,因为这将是我应用程序现有用户的全部意义所在!您是否必须再次保存每个实体才能使其正常工作?我也希望有一种方法可以查看 iCloud 同步的进度,因为它看起来非常缓慢。

标签: ios swift core-data cloudkit nspersistentcloudkitcontainer


【解决方案1】:

我找到了适用于我的 Core Data 数据库的解决方案 - 我的数据库非常复杂,具有多个多对多关系(一个名为 Somnus 的手术/麻醉日志应用程序)

我首先为我的所有核心数据实体创建了一个名为sentToCloud 的新属性,并在核心数据模型中将其默认设置为FALSE

在第一次加载现有用户时:

  • 为每个实体类型使用谓词"sentToCloud == FALSE" 获取请求
  • 将每个对象的 sentToCloud 更改为 TRUE,然后保存 MOC
  • 这会触发NSPersistentCloudKitContainer 开始同步

假设 iCloud 同步会话与修改核心数据的顺序相匹配,我已按照适用于我的数据库的“优先级”顺序执行此操作。在我的测试中似乎是这样:

  • 我首先同步所有子实体(或大多数类似儿童的实体)
  • 然后同步他们的父母,依此类推,上树
  • 我同步用户最后与之交互的对象,一旦其他一切都到位,因此关系完好无损,并且在我们等待 NSPersistentCloudKitContainer 重新连接所有关系时,他们不会认为他们的数据有问题
  • 我还将所有二进制数据(神奇地变成 CKAsset 幕后)留到最后,因为它不是我数据库中最重要的部分

我的数据库已成功从 iPad 同步到 iPhone,所有关系和二进制数据都显示正确。

现在我只需要一种方法来告诉用户数据何时同步(和/或某种进度)并让他们完全关闭它。

附录

在重置 iCloud 仪表板上的所有数据并删除我的 iPhone 和 iPad 上的应用程序后,我再次尝试了此操作。

第二次只同步了部分数据。处理大型同步请求似乎仍然存在问题(控制台中有很多.limitExceeded CKErrors)。

令人沮丧的是,尚不清楚它是否会破坏重试请求 - 我认为不是。我已经把它放了一夜,仍然没有进一步同步,只有更多 .limitExceeded CKErrors。

也许这就是他们不想同步现有数据的原因?

就个人而言,我认为这很愚蠢。有时用户会对他们的数据进行批处理,这将涉及在一次操作中更新数千个 Core Data 对象。如果这只是被.limitExceeded CKErrors 卡住,NSPersistentCloudKitContainer 不会是一个很好的同步解决方案。

他们需要一种更好的方法来处理这些错误(将请求分解为更小的请求),以及查看正在发生的事情的能力(并且可能向用户展示一些 UI)。

我真的需要它来工作,因为就目前而言,没有办法使用 CloudKit 同步多对多核心数据关系。

我只是希望他们仍在努力研究这个课程并改进它。

【讨论】:

  • 您似乎可以在每台设备上关闭 iCloud 同步(在“设置”->“iCloud”中),但是当您这样做时,设备上的所有数据都会被删除......而且它似乎会删除所有 iCloud 数据也会传播到其他设备(即使您没有关闭它们上的 iCloud)——如果你问我,这有点吓人......
  • 更新上述评论:如果您在设备上关闭 iCloud 同步,服务器数据似乎仍然存在,如果您再次打开它,它将重新填充您的应用程序。但似乎没有办法断开 iCloud 同步并保留本地数据。给用户一个选择就好了。
  • 保留本地数据但关闭同步的一种方法是在您的应用程序中设置一个设置,将您的 NSPersistentContainer 切换为普通 NSPersistentContainer 或 NSPersistentCloudKitContainer。我发现如果这样做,您必须在原版容器上设置 NSPersistentHistoryTrackingKey。
猜你喜欢
  • 2020-01-30
  • 2020-03-27
  • 2021-11-30
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
相关资源
最近更新 更多