如何高效地在Core Data和CloudKit之间同步记录

35

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

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

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

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

当应用程序启动时,它还从CloudKit中获取更改,如果有更改,则使用新更改更新本地缓存(Core Data)。

我希望能够得到一个常见的同步模式。在哪里放置与Core Data方法同步的位置以及它们应该长什么样子?

非常感谢您提供关于此的任何信息或帮助。

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


Adelmaer,CloudKit存储有关其记录的元数据,最后更新时间,最后访问时间,权限等等。您可以将此数据复制到您的核心数据中,并在连接时进行交叉检查以查看是否有任何更新。您还应该查看此stackoverflow答案,里面可能会有一些有用的信息:https://dev59.com/fYHba4cB1Zd3GeqPNB9Z?rq=1 - user3069232
3个回答

22
自 iOS 13 开始,有新的 API 简化了开发人员之间的同步。我建议您观看关于 CoreData 和 CloudKit 的新同步的 WWDC19 会话。请注意,这些新的 API 仅适用于 iOS 13+。
视频:https://developer.apple.com/videos/play/wwdc2019/202/ 简而言之,您需要开始使用 NSPersistentCloudKitContainer 代替 NSPersistentContainer。这将使同步自动进行,并使用以最后一次写入为胜利的合并策略进行冲突自动解决。如果您想构建一个良好的工作应用程序,还需要进行一些修改以改进应用程序的同步。
官方文档可以在以下链接找到:
协同数据建模(无冲突副本数据类型)

在会议结束时,他们还演示了一个比默认的“最后一次写入者获胜合并策略”更好的同步合并示例。使用因果树(Causal Trees)可以让多个用户编辑同一个字符串(以及某种程度上的其他类型数据),而不会丢失任何数据。我强烈建议每个人阅读Archagon的这篇文章,它描述了这个过程的工作原理以及如何实现它(也包括CloudKit同步,但不是新的自动同步)。正如在会议中所演示的那样,您还可以使用CoreData和CloudKit之间的新的自动同步来实现这一点。


11

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

在iCloud中为Core Data设计

但是,Core Data与iCloud已被弃用。即便如此,它尚未停止使用,苹果公司目前也没有立即停用它,只是想阻止其使用。但是,它在合理化来自多个设备的更新方面存在问题。

无论如何,我一直在研究如何使用Cloud Kit实现这一点。有两个答案,第一个答案是使用以下内容;

GitHub中的Seam

第二个答案是手动完成;

为CloudKit进行设计

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

无论如何,我即将开始自己做这件事。 我会在有更多信息时更新此处内容。


1
不能发誓,但我认为核心数据无法进行iCloud共享,因此如果您需要该功能,则必须使用CloudKit实现。 - Jonny
6
自 iOS 10 开始,CoreData iCloud 功能已被弃用。实际上,它从来就没起作用过。 - pronebird
我的回复的第三行指出了这一点。除非说它从来没有起作用,但是现在有更好的解决问题的方法。 - Owen Godfrey
@OwenGodfrey,你能解释一下“现在有更好的解决问题的方法”吗?目前与CloudKit同步核心数据的最佳实践/方法是什么? - Jerland2
在iOS 13中,代码数据似乎被同步到自定义的私有区域。我想知道当我在我的CloudKit容器中分享记录时会发生什么,它会在其他人共享的数据库中发生吗?它是否仍会与其他用户的CloudKit容器同步? - Congruent Tech. UG

8
最近,苹果发布了一份指南,似乎回答了这个问题。请查看苹果的《维护 CloudKit 记录的本地缓存》以了解如何将 CloudKit 数据存储在设备上。
尽管此指南没有提供样例代码来写入设备,但它确实回答了其余的问题。这告诉您如何从 CloudKit 获取更改,并创建可以存储在设备上的数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接