【问题标题】:How to sync records between Core Data and CloudKit efficiently如何高效地在 Core Data 和 CloudKit 之间同步记录
【发布时间】:2017-08-06 20:05:27
【问题描述】:

我目前正在学习如何使用 CloudKit 框架,但缺乏说明如何同步 Core Data 和 CloudKit 的文档或示例。

我看过所有专门用于 CloudKit 的 WWDC 视频(2014、2015、2016),但没有一个告诉我们如何实现与 Core Data 的同步。我找不到任何新的示例、教程或书籍来展示如何实现这种同步。

我知道使用 CloudKit 的 Operations API(不是 Convenience API)并订阅更改是有效的,正如它在专门用于 CloudKit 的新 WWDC 2016 视频中所说,但与 CoreData 的映射是一个真正的问题。

例如,假设我想创建一个类似于 Notes 应用的应用。离线时,用户可以创建他的笔记并使用它们将它们保存到他的核心数据库中。当设备上线时,应用程序会检查服务器上发生的变化并将新创建的记录保存到服务器(CloudKit)。

当应用程序启动时,它还会从 CloudKit 获取更改,如果有更改,它会使用新的更改更新本地缓存(核心数据)。

我希望有一个通用的同步模式。与 Core Data 方法同步的位置以及它们应该是什么样子的?

不胜感激有关此的任何信息或帮助。

我正在使用 Swift 3、Xcode 8、iOS 10。

【问题讨论】:

  • Adelmaer,cloudkit 存储有关它拥有的记录、上次更新、上次访问、权限等的元数据。您可以将此数据复制到您的核心数据中,并在连接时进行交叉检查以查看您是否有任何更新。你也应该看看这个 SO 答案,可能是这里的东西stackoverflow.com/questions/24509782/…

标签: core-data swift3 ios10 cloudkit ckoperation


【解决方案1】:

从 iOS 13 开始,有一些新的 API 可以为开发人员简化这种同步。我建议您观看有关 CoreData 和 CloudKit 之间新同步的 WWDC19 会议。请注意,这些新 API 仅适用于 iOS 13+。

视频:https://developer.apple.com/videos/play/wwdc2019/202/

简而言之,您需要开始使用NSPersistentCloudKitContainer 而不是NSPersistentContainer。这将使同步工作自动使用自动冲突解决和最后写入者获胜合并策略。如果您想构建一个良好的工作应用程序,您还需要进行一些修改以改进您的应用程序的同步。

官方文档见:


协作数据建模(无冲突复制数据类型)

在会议结束时,他们还演示了一个比默认的“last-writer-wins merge strategy”更好的同步合并示例。 因果树的使用允许多个用户编辑相同的字符串(以及在某种程度上扩展其他类型的数据)而不会丢失任何数据。我真的建议大家阅读 this article from Archagon,其中描述了它是如何工作的以及如何实现它(也与 CloudKit 同步,但不是新的自动同步)。正如会话中所展示的,您还可以通过 CoreData 和 CloudKit 之间的新自动同步来实现这一点。

【讨论】:

    【解决方案2】:

    Apple 最近发布了一份指南,似乎可以回答这个问题。查看 Apple 的 Maintaining a Local Cache of CloudKit Records,了解如何在设备上存储 CloudKit 数据。

    虽然本指南未提供写入设备的示例代码,但它确实回答了其余问题。这告诉您如何从 CloudKit 获取更改并创建可以存储在设备上的数据。

    【讨论】:

      【解决方案3】:

      Core Data 已经为用户提供了同步到 iCloud 的能力。无需使用 CloudKit。

      Design For Core Data In iCloud

      但是,带有 iCloud 的 Core Data 已被弃用。即便如此,它有not been discontinued,而且苹果公司没有立即停止它的计划,他们只是想阻止它的使用。但它在合理化多个设备的更新方面也存在问题。

      无论如何,我自己一直在研究如何使用 cloud kit 做到这一点。两个答案;首先是使用以下内容;

      Seam in GitHub

      第二种是手动做;

      Designing for CloudKit

      这里的关键是 Cloud Kit 需要记录元数据才能可靠地处理记录更新,因此您必须将该元数据保存在您的 Core Data 数据库中。 CKRecord 类包含一个方法 encodeSystemFields(with:),它将这些字段编码为可以存储在数据库中的数据记录,然后您可以在需要恢复 CKRecord 时使用适当的解码器。

      无论如何,我将自己开始这样做。当我有更多信息时,我会更新它。

      【讨论】:

      • 不能发誓,但我认为核心数据不能进行 iCloud 共享,因此如果您需要该功能,则必须使用 CloudKit 实现。
      • CoreData iCloud 自 iOS 10 以来已被弃用。它也从未工作过。
      • 我回复的第三行指出了这一点。除了说它从未奏效是愚蠢的。但是,是的,现在有更好的方法来解决这个问题。
      • @OwenGodfrey 你能解释一下“现在有更好的方法来解决这个问题”吗?与 CloudKit 同步核心数据的当前最佳实践/方法是什么?
      • iOS 13 中的代码数据似乎同步到了一个自定义的私有区域,我想知道当我在 CloudKit Container 上共享记录时会发生什么,是否会发生在其他人共享的数据库中?是否仍会与其他用户 CloudKit Container 同步?
      猜你喜欢
      • 2021-07-19
      • 2017-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-03
      • 2012-07-05
      • 2015-11-08
      相关资源
      最近更新 更多