CloudKit Sharing

孤街醉人 提交于 2019-12-05 04:35:55

问题


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.


回答1:


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")
            }
        }
    }
}



回答2:


I didn't understand quite well when you want to get those informations. I'm with the same problem as you, but I only can get the shared data by clicking the URL... To do that you'll need two functions. First one in AppDelegate:

func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) {

    let acceptSharesOperation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata])
    acceptSharesOperation.perShareCompletionBlock = {
        metadata, share, error in
        if error != nil {
            print(error?.localizedDescription)
        } else {
            let viewController: ViewController = self.window?.rootViewController as! ViewController
            viewController.fetchShare(cloudKitShareMetadata)
        }
    }
    CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptSharesOperation)
}

in ViewConroller you have the function that will fetch this MetaData:

func fetchShare(_ metadata: CKShareMetadata) {
    let operation = CKFetchRecordsOperation(recordIDs: [metadata.rootRecordID])
    operation.perRecordCompletionBlock = { record, _, error in
        if error != nil {
            print(error?.localizedDescription)
        }
        if record != nil {
            DispatchQueue.main.async() {
                self.currentRecord = record
                //now you have your Shared Record
            }
        }
    }
    operation.fetchRecordsCompletionBlock = { _, error in
        if error != nil {
            print(error?.localizedDescription)
        }
    }
    CKContainer.default().sharedCloudDatabase.add(operation)
}

As I said before, I'm now trying to fetch the ShareDB without accessing the URL. I don't want to depend on the link once I already accepted the share. Hope this helps you!



来源:https://stackoverflow.com/questions/40603657/cloudkit-sharing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!