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

hst*_*tdt 9 core-data swift xcode11 nspersistentcloudkitcontainer

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

IDE:Xcode11 beta3

在此处输入图片说明

这是Folder实体。

在此处输入图片说明

Bil*_*son 13

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

Cloud kit 不能使用有序关系(这很糟糕,因为有序数据是存在的基本事物)。原因是一切都由 CKRecord(云套件记录)支持,而不是实际的核心数据内容——它是一种完全不同类型的数据存储,并且 PersistentCloudKitContainer 正在将您的数据即时重写到 CKRecords 并返回。CKRecords 没有按照我们在 Core Data 有序关系中所需的方式来维护有序项目日志的机制。

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

所以...

你有几个不好的选择:

  1. 不要有正式的关系——而是有一个你存储的字段,例如,一个参考列表。在添加/删除子对象时自己维护它。基本上在父记录中有一个“管理员”字段,用于维护自己的关系机制。(例如:为每个孩子生成一个 UUID,父母为所有孩子存储一个 UUID 的串联列表)
  2. 使用 CoreData 关系,并将排序数据存储在子对象中,例如您手动维护的 orderIndex int 字段。
  3. 混合型:使用无序的关系从父母的孩子,也是“孩子的秩序”的字段存储在父。CoreData 管理关系,您可以根据需要手动维护和应用这些子项的排序。

不管你做什么,都是不好的:

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

  2. 在子对象中排序(这是我使用的):您必须在子对象的每个添加和删除操作中插入自己,运行代码以调整所有子对象的 orderIndex 值。我通过使用 CoreDataManager.createChild(atIndex:)、CoreDataManager.deleteChild() 和 CoreDataManager.moveChild(toIndex:) 函数来管理它,这些函数应用更新 orderIndex 值的副作用。但至少你会得到“获取父级;在 parent.children 中的 c 做......”并级联删除。但是:现在孩子只能在一个父母的列表中,因为孩子只有一个 orderIndex 值。

  3. 关系 + 手动维护父级排序字段:让核心数据管理关联,当您需要排序子级时,您可以使用 parent.orderedChildren() 函数读取父级的 .childOrder 字段,将其应用于 .children 列表。但是...您仍然必须手动管理父级的 .childOrder 字段,并在每次添加/删除/重新排序子项时更改它。但是,使用 Cloud Sync,您的 .child 列表和 .childOrder 字段值会随着子项在不同应用程序实例中添加/删除而变得不同步,因此存在许多潜在错误。保持子列表和排序分开意味着它们可以通过云同步单独更新。