I am not sure if I understand you right, but I will try an answer:
Assume a record hierarchy or a zone in the private database should be shared by the owner.
When sharing is initiated a user is invited to share the data, and a CKShare
record is initialized in the owner's private database.
When a user accepts the invitation, the CKShare
record and the shared data are made accessible for the user via the user's shared database. They are not copied to the shared database; the shared database is just a window to the private database of the owner. However if the shared database is mirrored by CoreData + CloudKit to a persistent store of the share user, NSManagedObjects
are created for the shared data.
When the owner or the user stops sharing, these NSManagedObjects
must normally no longer be accessible by the user. In principle this is also handled by iCloud mirroring: The shared database is no longer a window to the owner's data, i.e. it no longer contains the CKShare
record and the shared data, and thus mirroring deletes them from the user's persistent store. But this may take long. To delete the local copies of the shared data faster, one can call persistentContainer.purgeObjectsAndRecordsInZone
.
Now to your question that I do not understand: What do you mean by "deep copy the CKShare
back to the private zone"? The owner's private database has never been modified (except from updating the user's status in the CKShare
record or - when sharing stopped for the last user - the deletion of the CKShare
record). So there is no need to copy back the CKShare
record. The user's private database has neither been modified.
The only situation where a "deep copy" back to the private database makes sense to me is when the share user wants to keep the shared data even after sharing stopped. If you want to do this, you had to copy all shared objects as soon as they become available, i.e. as soon as they are mirrored from the iCloud shared database to the local persistent store. You could use a .NSPersistentStoreRemoteChange
notification to do the copying. purgeObjectsAndRecordsInZone
would then only delete the originals, not the copies.
EDIT:
Let's take an example:
A user, called here "owner", has some owner records in a CoreData persistent store that is mirrored to iCloud to the owner's private database.
During setup, iOS creates in the owner's private database a new zone "com.apple.coredata.cloudkit.zone".
Assume first that no records are shared.
Then iOS will update the persistent store of all devices logged in to the same iCloud account:
Local changes are exported to this zone in the owner's private database, and iCloud changes are imported to the owner's persistent store.
Now assume that the owner invites another user, called here "participant", to share either an owner's record hierarchy or an owner's zone.
Then, a CKShare
record is created in the owner's private database that specifies the sharing details, i.e. what is shared by whome.
The participant, who has the same app, has some participant's records in the participant's persistent store that is mirrored to the participant's private database.
During setup, iOS creates in the participant's private database a new zone "com.apple.coredata.cloudkit.zone".
When the participant accepts the owner's invitation to share data, iOS maps the owner's shared data to the participant's shared database. "Mapping" means that the owner's data that are in the com.apple.coredata.cloudkit.zone zone in the owner's private database appear now in the participant's shared database in a new zone "com.apple.coredata.cloudkit.zone". Together with the shared data, the CKShare
record of the owner's private database is also mapped to the participant's shared database.
This zone is now mirrored by iOS to the participant's persistent store.
For the owner, nothing has changed except the CKShare
record.
When the owner or the participant stops sharing, the mapping of the owner's data in the owner's private database is terminated, i.e. the owner's shared data no longer appear in the participant's shared database.
Since they are deleted for the participant (but not for the owner), this is mirrored to the participant's persistent store and the shared records are deleted in the participant's persistent store. However, this takes a while. In order to delete the shared data immediately, one can use persistentContainer.purgeObjectsAndRecordsInZone
when sharing is terminated.
I hope this clarified the situation!