使用CoreData和CloudKit

时间:2017-10-27 00:15:03

标签: ios core-data cloudkit

TLDR版本:我的应用程序如何知道设备A上的CoreData对象,设备B上的CoreData对象和CloudKit 中的CKRecord都是相同的记录

详细信息版本:

我正在开发一个在本地使用CoreData和CloudKit在设备之间进行同步的应用。一旦添加了多个设备,我就无法理解CoreData关系和CloudKit引用应该如何协同工作。

我理解他们的一些事实:

1)创建CoreData对象时,会为其分配一个objectID。您不能自己创建一个或修改已存在的一个。从CoreData关系字段,您可以直接访问相关对象,或者您可以使用便捷方法获取这些相关对象的objectID。

2)创建CloudKit记录时,可以为其分配recordName(基本上是CloudKit等效于CoreData objectID),或者默认生成一个。 CloudKit引用字段包含一个字符串,该字符串是关联记录的recordName。

所以这就是我的应用程序如何工作(并且不起作用)

设备A第一次启动。 CoreData实例化一组默认对象,用户可以在使用该应用程序时对其进行编辑(或添加/删除)。设置完成后,应用程序确定一切都是go,它会与CloudKit同步。它首先查看已经存在的任何记录(无),并使用CoreData objectID作为CloudKit recordNames将新记录上传到CloudKit。因此,Device A上的objectID和CloudKit recordNames是相同的。这些不同的对象之间存在多种关系。到目前为止一切都很好 - 这部分有效(正确修改了coredata中的仪表板更新关系,反之亦然)。

现在,随着设备B首次启动,现在情况有所不同。 CoreData实例化同一堆默认对象(具有唯一的objectID),然后用户可以在使用应用程序时修改或添加/删除。当设置完成并且一切都是go时,它会与CloudKit同步。它从CloudKit中下拉所有现有记录并更新匹配的本地记录。匹配永远不会发生基于recordName< - > objectIDs,因为Device B具有唯一的objectID。这是我理解不足的地方。

我目前尝试的解决方案

我的解决方案目前是向CoreData实体和CloudKit记录添加自定义ckID字段。在每台设备上的第一次同步时,它尝试以适当地同步这些字段。如果CloudKit中有记录,它会通过这些记录并尝试根据自定义字段和实体类型将现有CoreData对象与那些CloudKit记录进行匹配 - 例如,' name'实体领域。当找到匹配项时,它会在本地更新ckID字段。如果没有找到,则会生成一个新的CoreData对象。只要应用程序查找CoreData关系或创建CKReference,就会使用此ckID字段。总的来说,这感觉就像我做了很多我不应该做的工作。

提前感谢您的帮助!

更新11/3/17

一周后,整体而言,这似乎是错误方式在设备之间进行同步。我的自定义ID字段不同步导致各种混乱。

我仍然相信我在这里遗漏了一些非常基本的东西。记录如何在不同的位置与自身相关?如果可以修改现有的CoreData objectID(或在创建时分配一个),这将很容易 - 我缺少什么?!?我现在正在做的事情感觉非常错误但是我正在努力不知道还有什么可以尝试......

1 个答案:

答案 0 :(得分:1)

如前所述,DeviceID和Device B上的objectID会有所不同。 如果你真的想避免对象中的标识符字段,你可以在每个设备上保持查找以从recordName映射到objectID,但是如果你更新了你的核心数据模型你的objectID会改变,所以这个方法会非常不灵活。

您使用ckID字段的方法是正确的,是的,您实际上需要做这么多工作。 CloudKit只是一个传输层,实现同步是一种自己的野兽。

我建议您查看现有的解决方案,例如EnsemblesSeamSyncKit(其中我是作者)