When I checked Used with CloudKit
, the error Folder.children must not be ordered
appeared. Any idea about an ordered relationship?
IDE: Xcode11 beta3
Here's the Folder
Entity.
NSPersistentCloudKitContainer is a subclass of NSPersistentContainer capable of managing both CloudKit-backed and noncloud stores. By default, NSPersistentCloudKitContainer contains a single store description, which Core Data assigns to the first CloudKit container identifier in an app's entitlements.
Persistent storage has become an essential part of the majority of iOS apps nowadays. Core Data is a persistence and/or in-memory cache framework that consists of a very powerful set of other tools that can be used within the app.
(applies: as of iOS 13, and early betas of 14)
Cloud kit can't use ordered relationships (which just blows, as ordered data is a fundamental Thing That Exists). The reason is that everything is backed with CKRecord (cloud kit records) not actual core data stuff -- it's a completely different type of data storage, and the PersistentCloudKitContainer is doing on-the-fly rewrites of your data to CKRecords and back. CKRecords don't have mechanisms that work for maintaining journals of ordered items the way we need in Core Data ordered relationships.
Which means it's not likely to be "fixed" anytime soon, as it would require changes to CloudKit and apple's iCloud generally (vs. just changes to CoreData).
So...
You have a few not-good choices:
No matter what you do, it's bad:
No relationships: no "fetch parent" and get references to children via relationship; you have to fetch both separately. Also no "delete" rules done for you, e.g. " on delete parent, cascade delete children." This works when you need children in more than one collection (as each collection record keeps it's own list of children)
Ordering in child objects (this is what I use): you have to insert yourself in every add and delete operation on children, running code to adjust orderIndex values of all children. I manage this by having a CoreDataManager.createChild(atIndex:), CoreDataManager.deleteChild() and CoreDataManager.moveChild(toIndex:) functions that apply side effect of updating orderIndex values. But at least you get "fetch parent; for c in parent.children do..." and cascade delete's back. However: now child can only be in one parent's list, as child only has one orderIndex value.
Relationship + manually maintained ordering field in parent: let core data manage the association, and when you need ordered children you can use a parent.orderedChildren() function that reads your .childOrder field of parent, applies it to .children list. But... You still have to manage the parent's .childOrder field manually, and change it every time you add/remove/reorder children. HOWEVER, with Cloud Sync, there are many potential bugs wit your .child list and .childOrder field value getting out of sync as children are added/removed in different app instances. Keeping the child list and the ordering separate means they can be updated by cloud sync separately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With