What is the best-practice for deleting/leaving a share?
I'm trying to figure out how to stop sharing a record you've previously shared, as well as how to leave a share you've previously joined that someone else has shared. Hopefully I've just missed the documentation around this point, but I see little on the topic.
Can someone confirm or correct this approach? Thanks.
Say Alice has a record named record-A.
Alice shares record-A Alice's privateCloudDatabase now contains a cloudkit.share record.
Alice's record-A.share is set to a reference to that cloudkit.share.
Bob joins the share Bob's sharedCloudDatabase now contains a cloudkit.share record referencing Alice's cloudkit.share?
Bob wants to leave the share QUESTION: Is it enough to simply delete Bob's cloudkit.share in his sharedCloudDatabase?
Alice wants to stop sharing QUESTION: Is it enough to simply delete Alice's cloudkit.share in her privateCloudDatabase?
QUESTION: When Alice stops sharing, is Bob's cloudkit.share automatically deleted from his sharedCloudDatabase?
Post
Replies
Boosts
Views
Activity
What's the best way to detect—and announce—when participants join and leave a share?
I'm evaluating whether it's possible and practicable to announce to the owner of a share when participants join or leave the share, but having trouble determining these events with precision.
Consider:
Alice shares her list of recommended restaurants and invites Bob and Carol to join.
Bob accepts the invite and joins the share.
Carol later accepts the invite and joins the share.
Question #1: Alice knows her cloudkit.share record has been updated and can examine the participants, but how can she determine who just joined? I don't see a "dateJoined" field or anything to differentiate the participants chronologically.
Bob leaves the share.
Question #2: Alice knows her cloudkit.share record has been updated, but how can she determine that it was Bob that just left? He's no longer in the participants list.
The docs say an acceptanceStatus of .removed means "the participant was removed from the share", but I'm seeing something different and wondering if there's a case I'm missing.
The setup
Alice has shared record-A, and Bob and Carol have joined successfully.
When the joined participant leaves
Bob decides to leave the share, displays the sharing controller, and chooses "Remove Me".
This doesn't mark the participant as .removed, but rather reverts the participant to .pending (which the sharing controller relists as "invited").
When the owner removes the participant
Alice decides to remove Bob's access, displays the sharing controller, and chooses "Remove Access".
This doesn't mark the participant as .removed, but rather simply removes the participant from the participants list altogether.
So, when and how is .removed used?
If I call collectionView.isEditing = true, nothing happens. What I'd expect is the collection/list to animate into editing mode. How is this done?
If I need to write a child record of a shared root record, what's the best way to determine whether I write it to the private or shared database?
For shared root records, record.share is non-nil. But for child records of that root record, record.share is nil.
I understand that child records have a parent reference that can be resolved to determine whether the parent has a share, but resolving that reference is increasingly expensive the more deeply the child is nested.
Given an arbitrarily deeply nested child record, is there a cheap and canonical way to determine whether the record should be written to the shared database?
In a shared zone you have a root record—call it "Root".
You create a child record, "childA", assign Root as its parent, and write it to the cloud with Operation1.
Before Operation1 has completed, you create a second record, "childB", assign Root as its parent, and write it to the cloud with Operation2.
Operation1 completes without error.
Operation2 completes with an error, saying Parent had changed.
(Presumably, the error in step 5 was because Parent was changed somehow by Operation1, but how—and why? Parent itself did not change, though a reference to it had been created via child1.parent.)
Resend the failed record from step 3 with Operation3.
Operation3 completes without error.
Step 7 succeeded because the parent had been refreshed in the local cache, but why should that matter? And if it does matter, what then is the best practice for rapid and successive additions of child records to a common parent record?
Perhaps I am encountering this issue more because my home internet connection is abysmally slow at the moment, but surely you don't need to synchronously daisy-chain successive child insertions, so what I am missing?
I understand that batching both child insertions into the same operation would sidestep this issue, but the child records are created sequentially by the user (think items in a list) and are written to the cloud separately.
What's the best practice here? (Thanks for your time.)
When saving a record, I'm getting an error relating to the record's parent record, which I'm specifying for sharing. Normally, things work fine, but occasionally I see this error:
<CKError 0x2817841b0: "Internal Error" (1/5001); "Parent record <CKRecordID: 0x105b26f70; recordName=EC8418DB-A9DC-4CCE-ADEB-E1548237DA19, zoneID=SharedShoppingZone:defaultOwner> in the same batch didn't have chain PCS data on it for record <CKRecordID: 0x105b48600; recordName=32EE1E4C-0DE9-4E88-B284-A3DBFC0AABE9, zoneID=SharedShoppingZone:defaultOwner>">.
Beforehand I'm fetching the parent record afresh so it is current, but what is the cryptically-named "chain PCS data" and what is this error attempting to tell me?
Thanks for any help.
My iPad isn't receiving CloudKit notifications as expected when connected to Xcode through "Connect via network" (wirelessly).
My setup:
• iPhone - connected to Xcode via USB
• iPad 1 - connected to Xcode via USB
• iPad 2 - connected to Xcode via "Connected via network"
All three devices are built and running in the debugger. On the iPhone, I change something, the change gets saved to iCloud successfully, and I see the change reflected quickly on iPad 1, but never on iPad 2. Setting breakpoints to detect the remote notifications show they never arrive at all on iPad 2.
Is this a limitation of Bonjour connections, or a bug?
Are the user icons/avatars seen in UICloudSharingController available through an API? I don't see them in CKUserIdentity or CKUserIdentity.LookupInfo...
UICloudSharingController calls delegate.cloudSharingControllerDidStopSharing() when a share is successfully unshared.
Is there an equivalent call when a failure occurs during share deletion, similar to the delegate.failedToSaveShareWithError() called when the share is being created?
I'm asking because I want to provide appropriate feedback for both success and failure scenarios when the user taps Stop Sharing.
I am hoping you can tell me what's possibly different here.
Devices A and B are shared participants in a shopping list.
I've confirmed:
• both are on the Production environment
• both have database subscriptions to private and shared
What I'm seeing:
• A (share owner) sees items added by B.
• B (invitee) does not see items added by A. If B syncs then it sees the items, but it receives no related remote notifications at all, despite the subscriptions (yet A does receive them)
Seems like these two devices should be the same, but what might be causing B to not get the remote notifications?
Thanks for any pointers.
Does iCloud Drive need to be enabled in order to determine whether someone is signed into iCloud? Because it seems like it does, which I don't recall reading anywhere before.
With iCloud Drive disabled, a call to CKContainer.default().accountStatus() returns status: CKAccountStatus.noAccount, error: nil
With iCloud Drive enabled, the same call returns status: CKAccountStatus.available, error: nil.
I had a user report that syncing wasn't working, and it turned out that she had disabled iCloud Drive, not knowing what it was or whether it benefited her.