This is the fifth in an eight-part series on implementing data sharing in Shopping UK using CloudKit.
Shopping UK is a smart shopping list for UK shoppers. It knows almost every product in the supermarket and will arrange them by aisle. Lists can be shared with family or friends.
Last week, we looked at how sharing works and how to start sharing the list. Today, we’ll look at what happens when another device accepts an invitation to collaborate on a shared list.
A sharing invitation is sent from the owner to one or more participants, typically via Messages or Email. The “owner” is the account that initiates the sharing.
The invitation itself is just a link to iCloud, like this:
https://www.icloud.com/share/0123456789abcdefghijklmno#Shopping
The fragment (i.e. the part after the #) is the title of the share, in this case, “Shopping”.
When a user clicks on the invitation link, iOS first checks if the app is installed, and it is right version to accept shares.
The CKSharingSupported key in info.plist indicates this.
Before releasing v3.3 (the first version of Shopping UK to support CloudKit sharing), I released v3.2, which had sharing enabled. The idea was to improve the adoption of sharing. When v3.3 was published, all existing v3.2 users could accept shares immediately without having to first update their app.
Once the system completes its checks, the user sees a message:
After the user accepts the link, iOS calls userDidAcceptCloudKitShareWith.
A CKShare.Metadata object is provided as a parameter. This has everything the app needs to find the shared data in iCloud.
To accept the share, Shopping UK sends a CKAcceptSharesOperation message to the identified CKContainer.
CloudKit will change the participant’s status from Pending to Accepted.
Note: Before calling CKAcceptSharesOperation, Shopping UK checks the list hasn’t already been added to the device. If it already exists, the shopping list is opened in the app.
The app creates a new empty list on the device using the info in CKShare.Metadata:
List Property | Copied From |
---|---|
ListId | RootRecordId Name |
ListName | CKShare’s CKShareTitleKey |
ZoneId | RootRecordId ZoneId |
Database | “shared” |
This confused me initially, but this is what I learned:
When Alice shares a list, it is uploaded to her Private CKDatabase.
But, when Bob accepts the invitation to join Alice’s list, the same records are visible to him in his Shared Database. Both accounts can make changes to the underlying data via their respective database: Alice via her Private database and Bob via his Shared database.
Data appears in a different database depending on whether your iCloud account is the owner or a participant.
Next, the app fetches a list of changes using Fetch Changes (described in Part 3). But the CKServerChangeToken is ignored to ensure all changes are fetched.
As changes are received, the app applies them to the new list then shows the list to the user.
Next week, we’ll take a closer look at how data is synchronised between devices and some of the challenges to consider.
If you get a chance, please try Shopping UK and let me know what you think at @wheelies