Search code examples
ioscloudkit

CloudKit Sharing


I am having trouble understanding some of the CloudKit sharing concepts and the WWDC 2016 "What's new in CloudKit" video doesn't appear to explain everything that is required to allow users to share and access shared records.

I have successfully created an app that allows the user to create and edit a record in their private database. I have also been able to create a Share record and share this using the provided sharing UIController. This can be successfully received and accepted by the participant user but I can't figure out how to query and display this shared record.

The app creates a "MainZone" in the users private database and then creates a CKRecord in this "MainZone". I then create and save a CKShare record and use this to display the UICloudSharingController.

How do I query the sharedDatabase in order to access this record ? I have tried using the same query as is used in the privateDatabase but get the following error:

"ShareDB can't be used to access local zone"

EDIT

I found the problem - I needed to process the accepted records in the AppDelegate. Now they appear in the CloudKit dashboard but I am still unable to query them. It seems I may need to fetch the sharedDatabase "MainZone" in order to query them.


Solution

  • Dude, I got it: First you need to get the CKRecordZone of that Shared Record. You do it by doing the following:

    let sharedData = CKContainer.default().sharedCloudDatabase
        sharedData.fetchAllRecordZones { (recordZone, error) in
            if error != nil {
                print(error?.localizedDescription)
            }
            if let recordZones = recordZone {
                // Here you'll have an array of CKRecordZone that is in your SharedDB!
            }
        }
    

    Now, with that array in hand, all you have to do is fetch normally:

    func showData(id: CKRecordZoneID) {
    
        ctUsers = [CKRecord]()
    
        let sharedData = CKContainer.default().sharedCloudDatabase
        let predicate = NSPredicate(format: "TRUEPREDICATE")
        let query = CKQuery(recordType: "Elder", predicate: predicate)
    
        sharedData.perform(query, inZoneWith: id) { results, error in
            if let error = error {
                DispatchQueue.main.async {
                    print("Cloud Query Error - Fetch Establishments: \(error)")
                }
                return
            }
            if let users = results {
                print(results)
                self.ctUsers = users
                print("\nHow many shares in cloud: \(self.ctUsers.count)\n")
                if self.ctUsers.count != 0 {
                    // Here you'll your Shared CKRecords!
                }
                else {
                    print("No shares in SharedDB\n")
                }
            }
        }
    }