如何设置与 NSPersistentCloudKitContainer 的有序关系?

How to set an ordered relationship with NSPersistentCloudKitContainer?

当我检查Used with CloudKit时,出现错误Folder.children must not be ordered。关于有序关系有什么想法吗?

IDE: Xcode11 beta3

这是 Folder 实体。

(适用:从 iOS 13 开始,以及 14 的早期测试版)

Cloud kit 不能使用有序关系(这只是打击,因为有序数据是存在的基本事物)。原因是一切都由 CKRecord(云工具包记录)支持,而不是实际的核心数据——这是一种完全不同的数据存储类型,PersistentCloudKitContainer 正在对您的数据进行 on-the-fly 重写到 CKRecords 并返回。 CKRecords 没有按照我们在 Core Data 有序关系中所需的方式维护有序项目日志的机制。

这意味着它不太可能很快被“修复”,因为它通常需要更改 CloudKit 和苹果的 iCloud(相对于仅更改 CoreData)。

所以...

您有几个 not-good 个选择:

  1. 没有正式的关系 -- 而是有一个存储字段,例如参考列表。当你 add/remove child objects 时,你自己维护这个。 parent 记录中基本上有一个“管理”字段,您可以使用它来维护自己的关系机制。 (例如:为每个 child 生成一个 UUID,parent 为所有 children 存储 UUID 的串联列表)
  2. 使用 CoreData 关系,并将订购数据存储在 child objects 中,例如您手动维护的 orderIndex int 字段。
  3. Mixed:使用从parent到children的无序关系,存储一个字段“children的顺序”在 parent。 CoreData 管理这种关系,您可以根据需要手动维护和应用这些 children 的排序。

无论做什么都不好:

  1. 没有关系:没有“获取parent”并通过关系获取对children的引用;您必须分别获取两者。也没有为您完成的“删除”规则,例如“删除 parent,级联删除 children。”当您在多个集合中需要 children 时,此方法有效(因为每个集合记录都有自己的 children 列表)

  2. Ordering in child objects(这是我用的):你必须在children上的每个添加和删除操作中插入自己,运行代码调整所有children的orderIndex值。我通过 CoreDataManager.createChild(atIndex:)、CoreDataManager.deleteChild() 和 CoreDataManager.moveChild(toIndex:) 函数来管理它,这些函数应用更新 orderIndex 值的副作用。但至少你得到了“fetch parent; for c in parent.children do...”并且级联删除返回。但是:现在 child 只能在一个 parent 的列表中,因为 child 只有一个 orderIndex 值。

  3. Relationship + manually maintained ordering field in parent:让核心数据管理关联,需要排序的时候children可以使用parent.orderedChildren () 函数读取您的 parent 的 .childOrder 字段,将其应用于 .children 列表。但是...您仍然需要手动管理 parent 的 .child 订单字段,并在每次 add/remove/重新订购 children 时更改它。但是,使用 Cloud Sync,您的 .child 列表和 .child 订单字段值不同步会存在许多潜在错误,因为 children 在不同的应用程序中是 added/removed实例。保持 child 列表和排序分开意味着它们可以通过云同步单独更新。