How to create a share with CloudKit's CKShare?

2019-07-10 04:01发布

问题:

I'm studying the new CKShare that Apple released this year and I have some questions with it. I was trying to follow the WWDC's "What's new in CloudKit" video but part of the code isn't working anymore in Xcode.

What I'm trying to do is: the user will enter his name and phone and after clicking a UIButton, will share with a specific person. Here is the code:

class ViewController: UIViewController, UICloudSharingControllerDelegate {
    @IBOutlet weak var nome: UITextField!
    @IBOutlet weak var telefone: UITextField!
    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func send(_ sender: AnyObject) {
        print("Send button was clicked.\n")

        let elder = CKRecord(recordType: "Elder")
        elder["name"] = self.name.text as CKRecordValue?
        elder["telephone"] = self.telephone.text as CKRecordValue?

        let ckContainer = CKContainer.default()
        let shareRecord = CKShare(rootRecord: elder)

        shareRecord[CKShareTitleKey] = "Elder" as CKRecordValue?

        let shareController = UICloudSharingController(share: shareRecord, container: ckContainer)
        shareController.delegate = self
        shareController.availablePermissions = [.allowReadOnly]
        shareController.popoverPresentationController?.sourceView = self.button

        self.present(shareController, animated: true)
    }

    func cloudSharingController(_ csc: UICloudSharingController, failedToSaveShareWithError error: Error) {
        print("PROBLEM SAVING SHARE")
    }

    func cloudSharingControllerDidSaveShare(_ csc: UICloudSharingController) {
        print("SHARE SAVED")
    }

    func itemTitle(for csc: UICloudSharingController) -> String? {
        return "a"   //don't know what this is for
    }
}

My app keeps printing "PROBLEM SAVING SHARE" even though the CloudSharingController appears. Also, the CKRecord elder isn't appearing in CloudKit's dashboard.

回答1:

So, I figured out what was wrong... I was using the default zone that cloud kit creates for you and you CANNOT do that when using CKShare. All you have to do is create a private custom CKZone and save the CKRecord and CKShare in it!



回答2:

I was told that you can use the initializer that you have chosen to use only if the share has already been created. For new shares, use the alternate init

Try this code:

let csc = UICloudSharingController { controller,
        preparationCompletionHandler in
        let share = CKShare(rootRecord: elder)

        let mro = CKModifyRecordsOperation(
            recordsToSave: [elder, share],
            recordIDsToDelete: nil)


        mro.modifyRecordsCompletionBlock = {
            records, recordIDs, error in
            if error != nil {
                    //handle error
            }
            preparationCompletionHandler(share,CKContainer.default(), error)
        }
        myDB.add(mro)
    }

    csc.delegate = self
    self.present(csc, animated:true, completion:nil)