Как установить упорядоченные отношения с NSPersistentCloudKitContainer?

Когда я проверял Used with CloudKit, Ошибка Folder.children must not be ordered появившийся. Есть идеи об упорядоченных отношениях?

IDE: Xcode11 beta3

Вот Folder Сущность.

0 ответов

(применимо: начиная с iOS 13 и ранних бета-версий 14)

Облачный комплект не может использовать упорядоченные отношения (что просто сбивает с толку, поскольку упорядоченные данные - это фундаментальная вещь, которая существует). Причина в том, что все поддерживается CKRecord (записи облачного набора), а не фактическими основными данными - это совершенно другой тип хранилища данных, и PersistentCloudKitContainer на лету перезаписывает ваши данные в CKRecords и обратно. В CKRecords нет механизмов, которые работают для ведения журналов заказанных элементов так, как нам нужно в упорядоченных отношениях Core Data.

Это означает, что вряд ли это будет "исправлено" в ближайшее время, поскольку для этого потребуются изменения в CloudKit и iCloud от Apple в целом (а не только в CoreData).

Так...

У вас есть несколько не очень хороших вариантов:

  1. Не иметь формальных отношений - вместо этого имейте поле, в котором вы храните, например, список ссылок. Сохраняйте это самостоятельно при добавлении / удалении дочерних объектов. По сути, имейте поле "admin" в родительской записи, которое вы используете для поддержки собственного механизма отношений. (например: сгенерировать UUID для каждого дочернего элемента, родительский элемент хранит объединенный список UUID для всех дочерних элементов)
  2. Используйте CoreData Relationships и сохраните данные для заказа в дочерних объектах, например, в поле orderIndex int, которое вы поддерживаете вручную.
  3. Смешанный: используйте неупорядоченные отношения от родителя к потомкам, а также сохраните поле "порядок потомков" в родителе. CoreData управляет отношениями, и вы можете вручную поддерживать и применять упорядочивание этих дочерних элементов по мере необходимости.

Что бы ты ни делал, это плохо:

  1. Нет отношений: нет "выборки родителя" и получения ссылок на потомков через отношения; вам нужно получить оба отдельно. Также для вас не применяются правила "удаления", например, "при удалении родителя, каскадное удаление потомков". Это работает, когда вам нужны дочерние элементы более чем в одной коллекции (поскольку каждая запись коллекции хранит свой собственный список дочерних элементов)

  2. Порядок в дочерних объектах (это то, что я использую): вы должны вставлять себя в каждую операцию добавления и удаления дочерних объектов, запускать код для корректировки значений orderIndex всех дочерних элементов. Я справляюсь с этим с помощью функций CoreDataManager.createChild(atIndex:), CoreDataManager.deleteChild() и CoreDataManager.moveChild(toIndex:), которые применяют побочный эффект обновления значений orderIndex. Но, по крайней мере, вы получаете "получить родителя; для c в parent.children do..." и каскадное удаление обратно. Однако: теперь дочерний элемент может быть только в списке одного родителя, поскольку дочерний элемент имеет только одно значение orderIndex.

  3. Отношение + вручную поддерживаемое поле упорядочивания в родительском элементе: позвольте основным данным управлять ассоциацией, а когда вам нужны упорядоченные дочерние элементы, вы можете использовать функцию parent.orderedChildren(), которая считывает ваше поле.childOrder родительского элемента и применяет его к списку.children. Но... Вам все равно придется вручную управлять родительским полем.childOrder и изменять его каждый раз, когда вы добавляете / удаляете / меняете порядок дочерних элементов. ОДНАКО с Cloud Sync существует множество потенциальных ошибок, связанных с рассинхронизацией вашего списка.child и значения поля.childOrder по мере добавления / удаления дочерних элементов в разных экземплярах приложения. Разделение дочернего списка и упорядочивания означает, что их можно обновлять с помощью облачной синхронизации отдельно.

Другие вопросы по тегам