I am trying to understand the concepts between two of the CloudKit code samples:
- CoreDataCloudKitDemo, which shows sync between CoreData and CloudKit
- CoreDataFetchedProperty which shows how you can keep public and private data in two CoreData configurations and join them together.
After some trial and error I created a single NSPersistentCloudKitContainer
that I thought used the two separate configurations - each had it's own local persistent store, database scope was set properly for both stores, etc. But when I run the app it complained of the following:
Failed to load persistent stores:Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={NSLocalizedFailureReason=CloudKit integration does not allow relationships to objects that aren't sync'd. The following relationships have destination entities that not in the specified configuration.
EntityA: entityB - EntityB
So, I went back to the model and although I had created two separate Configurations (with EntityA
in one and EntityB
in the other, I had not enabled them for use in CloudKit. When I did that, then the app now refuses to build.
This feels like a common scenario so I am assuming I have misconfigured something in the model. Are there any pointers that can help me correct this?
Thanks
`
hi Chris,
i did this separation of local and cloud configurations some time ago, and as i recall, the 2 problems that needs fixin' are:
- you cannot have a Core Data relationship between objects in the different configurations, so you have to implement any such relationship yourself; and
- you must designate that your cloud-based configuration attaches itself to the cloudkit container (while the local configuration does not).
the second requires a setting in the Core Data .xcdatamedeld file: tap on a configuration and check "Used with CloudKit in the Data Model Inspector.
the first is very cleverly, if not secretly, handled in CoreDataFetchedProperty in that there is a FetchRequest defined that makes it easy for objects in the local configuration to find associated objects in the cloud configuration by a UUID look-up (or it may be vice-versa, i can't remember right now).
that is, instead of a one-to-one relationship from A (local) to B (cloud) being defined in the Core Data model, assume that all A and B objects have been assigned UUIDs and that each object has an attribute maybe called associate
containing the other object's UUID.
given an A, you find the associated B by doing a fetchRequest on all Bs to find the one that matches the UUID you saved in A.associate. you do the same to find any A associated with a given B.
you can do either of these directly in code, maybe by adding a computing property as an extension to each; but in CoreDataFetchedProperty they pre-define such a Fetch directly in the Core Data model that can be called directly using an aggregate/computed property with a @fetch syntax. i'm sorry i can't recall the exact syntax, but examine the pre-define Fetch and the properties of the objects carefully to find the syntax for this.
hope this helps,
DMG