In the summer, Apple published an informative sample app on sharing objects between iCloud users using Core Data, CloudKit and UICloudSharingController in SwiftUI.
However, adding more participants using UICloudSharingController does not appear to work when used for Core Data with CloudKit.
MRE:
See the Apple sample app linked above.
The same problem also appears when using other sample apps, like the one from RayW.
The problem does not appear in samples that use pure CloudKit, such as this one by Apple.
Reproduction:
Expectation:
We can use UICloudSharingController to add new participants, using Messages, Mail or other platforms. The link will display correctly on all devices.
Reality:
On iOS16+, attempting to share via Messages engages the "Collaboration" framework and leads to an alert: "An Error Occurred. Unable to start collaboration" (see Image 1). A console warning appears (see below). Triggering this error breaks ANY further shares - the link now cannot be created for Mail and other platforms either (see Image 2). Furthermore, if the first attempt succeeds, the link does not appear correctly on the receiving device (see Image 3).
After further testing, UICloudSharingController also fails in iOS15 - it just dismisses the sheet rather than throw an alert on a compact device. UICloudSharingController is definitely bugged when showing an existing share.
Console logs:
The following console message appears when this issue happens for the first time:
Where "containerID" is the CKContainer ID, like “iCloud.com.company.samples.CoreDataCloudKitShare”. The message does not appear on subsequent attempts to add more people.
Question:
How can this be resolved, so that we can share Core Data records between users using CloudKit and UICloudSharingController?
EDITs:
shareObject(_:to:completionHandler:): Failed to share an object: Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={NSLocalizedFailureReason=NSPersistentCloudKitContainer does not support sharing objects across persistent stores. Objects must first be assigned to the correct persistent store (private, or shared as the case may be), so that they can be moved in to the correct record zone for sharing.})
As of 27 April 2023 and iOS 16.4, the issues described in the post were resolved by Apple.
After some back and forth with Apple in my TSI, I managed to build a working app with Core Data and CloudKit sharing.
On their side, Apple updated their sample app to reflect the issues discussed and the updates made to UICloudSharingController. Use the same link to check it out.
I would like to end this by saying that Apple engineers were very helpful in solving this and provided me with lots of tips. I am grateful for their assistance.
For others: you might struggle with adding objects to other user's CKShare (i.e. into the shared persistent store). This is a response from Apple on this that set me on the right track:
"The way to support the use case today is to relate the photo to an object that is already tied to a share (a shared tag, for example). That way, Core Data assigns the photo to the right record zone when saving it, just like what it does when you add a new tag to a shared photo from the participant side. It may be reasonable to introduce something like albums so users can tie a photo to a shared album."
Also, if you plan to show the same object between shares (e.g. a single Photo that might show up in multiple Albums), do not forget that relationships cannot be established across shared record zones. So you cannot have a single Photo with a relationship to multiple Albums.