NSPersistentCloudKitContainer and CloudKit for Sharing

Hello,


I've tried to figure this out for weeks now, but can't find a solution. I am not very experienced in App Development yet, so maybe it can be solved with little effort and I just don't know how...?


I am working on a baby journal app where parents should be able to share a child record together with all its entries (existing ones and ones that are going to be added in the future) to be able to both edit and add and look at entries. So, I need sharing like in the Apple Notes App.

I am using core data and the new NSPersistentCloudKitContainer. The core data model consists of a child record and entities that are referencing to the child.


I know that at the moment NSPersistentCloudkitContainer doesn't support sharing.

I have no clue how to add sharing with CKShare API beside the core data stuff. To have a proper solution, do I need to

a) throw away NSPersistentCloudKitContainer and solely base the app on CloudKit API with no core data at all?

b) add CloudKit Sharing via CKShare API, existing beside the core data stuff, so in the end I have core data entities and CKRecords? But how do I solve that in a proper manner?

c) sync the shared records into the core data database and subscripe to changes - so basically do a cloudKit-CoreData-Sync in addition for the shared databases....?


none of the above mentioned solutions sound really smart to me.... so I was wondering how Apple has solved this for the notes app. Is it based on cloudkit only or on NSPersistentCloudKitContainer and added sharing via CKShare API manually? Does it sync to coredata back and forth ?


And: What do you think how likely is it that Apple will support sharing for use of NSPersistentCloudKitContainer in the near future?


Thanks a lot for your help.

Katharina

Hi! I am dealing with the exact same issue in my app. I don't have a good answer for you, but I am pursuing option C from your list above. So far I am able to get a shared record from another user to appear in my shared database, so I don't think it will be a problem to create a core data entity from that shared record and subscribe to changes from that cloud record to update the local record whenever the other user makes a change. Seems overly complicated but I have not found a better way to do it yet.


Have you figured out how to get the CKSubscription to work on the shared database?


Let me know if you want to exchange code on this problem. Cheers.

thanks for your response.

I might give up for now until there's a better solution. Although I can't imagine that it's so complicated, because there should be so many apps out there that need to support collaboration...

haven't got CKSubscription to work yet.


Also I was thinking that when I add the CKShare Record to the Core Data private database, then it will be synced and part of core data database, which should complicate things as it might lead to doubled records? Or am I thinking the wrong way here?


Please let me know if you find a solution and if yes, what the solution looks like. I'll let you know as well.


Thanks!

Katharina

Yes, NSPersistentCloudKitContainer doesn't support sharing, you have to implemented that code manually. Here's a great walkthrough along with some sample code: https://developer.apple.com/documentation/cloudkit/sharing_cloudkit_data_with_other_icloud_users

You can obtain an NSManagedObject's underlying CKRecord using https://developer.apple.com/documentation/coredata/nspersistentcloudkitcontainer/3141668-record

Basically, you need to create a CKShare for each record you'd like to share. Don't forget to setup a CKDatabaseSubscription to get notified about changes. After changing the record, receivers of the share need to store it back to the shared database (and not to their private database, unless they're the owner of the record).
Can you clarify on why a CKSubscription is needed?

[Scenario A] User A shares a list of tasks with user B through a CKShare. User B gets access to the CKShare record and any modification made by user B is done directly to the CKShare object which represents a reference to the list of tasks of user A. The same applies to modifications made by user A -- they would be directly reflected on the CKShare record. Why would I need a CKSubscription in this case?

[Scenario B] The only scenario where a CKSubscription would be needed is if CKShare is copied over to user B's Core Data/CloudKit. Then I would implement a CKSubscription to notify the Core Data object on user B's end of any change to CKShare and vice versa.

What does Apple recommend: Implementing A or B?
NSPersistentCloudKitContainer and CloudKit for Sharing
 
 
Q