I am using the following code to attempt to create a shared private record:
@IBAction func testPress(_ sender: Any) { let customZone = CKRecordZone(zoneName: "ShareZone") let friendRecord = CKRecord(recordType: "Share", zoneID: customZone.zoneID) let rootRecord = CKRecord(recordType: "Root", zoneID: customZone.zoneID) model.privateDB.delete(withRecordZoneID: customZone.zoneID) { (nil, error) in self.model.privateDB.save(customZone) { (nil, error) in print("Custom Zone Error = \(error)") self.model.privateDB.save(friendRecord, completionHandler: { (nil, error) in self.model.privateDB.save(rootRecord, completionHandler: { (nil, error) in self.shareTest(record: friendRecord, root: rootRecord) }) }) } } } func shareTest(record:CKRecord, root:CKRecord) { record["Name"] = "Test" as CKRecordValue? root["Name"] = "Test" as CKRecordValue? let ckContainer = CKContainer.default() let shareRecord = CKShare(rootRecord: root, share: record.recordID) shareRecord[CKShareTitleKey] = "Name" as CKRecordValue? let shareController = UICloudSharingController(share: shareRecord, container: ckContainer) shareController.delegate = self shareController.availablePermissions = [.allowReadOnly] self.present(shareController, animated: false) } However I am returning the error when I press on a way to share the link:
CKError 0x6000002535f0: "Invalid Arguments" (12); "An added share is being saved without its rootRecord (CKRecordID: 0x608000224560; recordName=C0ADC819-57F7-4D99-A527-B21590F506AB, zoneID=ShareZone:defaultOwner)"
I looked at this answer Link who was having the same problem, but do not quite know how to get their solution to work as they didn't provide enough details.
Does anyone know what I am doing wrong?
1 Answer
I believe the error message is telling you need to save the share and root record at the same time.
let modifyRecordsOperation = CKModifyRecordsOperation( recordsToSave: [record, share], recordIDsToDelete: nil) You should do this operation in the completion handler of the sharingController.
sharingController = UICloudSharingController { controller, preparationCompletionHandler in Edit: Your code would look something like this not tested code:
@IBAction func testPress(_ sender: Any) { let privatedatabase = CKContainer.default().privateCloudDatabase let newZoneName = UUID().uuidString let recordZone = CKRecordZone(zoneName: "ShareZone") privatedatabase.save(recordZone) { savedRecordZone, error in if let error = error { print("\(error.localizedDescription).") } else if let savedRecordZone = savedRecordZone { print("\(error.localizedDescription).") let rootRecord = CKRecord(recordType: "RootRecord", zoneID: savedRecordZone.zoneID) rootRecord["Name"] = "Test" as CKRecordValue? privatedatabase.save(rootRecord) { record, error in if let error = error { print("\(error.localizedDescription).") } else if let record = record { print("successfully added rootRecord to cloud.") self.shareTest( rootRecord: record) } } } } } func shareTest(rootRecord:CKRecord) { let ckContainer = CKContainer.default() let shareRecord = CKShare(rootRecord: rootRecord) let sharingController = UICloudSharingController { controller, preparationCompletionHandler in let share = CKShare(rootRecord: record) share[CKShareTitleKey] = "Share Title" as CKRecordValue share.publicPermission = .none let modifyRecordsOperation = CKModifyRecordsOperation( recordsToSave: [rootRecord, share], recordIDsToDelete: nil) modifyRecordsOperation.timeoutIntervalForRequest = 10 modifyRecordsOperation.timeoutIntervalForResource = 10 modifyRecordsOperation.modifyRecordsCompletionBlock = { records, recordIDs, error in if let error = error { print(error.localizedDescription) } if let records = records { print("Share and Root records saved successfully") } preparationCompletionHandler(share, CKContainer(identifier: ckContainerID ), error) } myCloudDatabase.add(modifyRecordsOperation) } if let sharingController = sharingController { sharingController.availablePermissions = [.allowReadOnly, .allowReadWrite, .allowPrivate] sharingController.popoverPresentationController?.sourceView = sender sharingController.delegate = self self.present(sharingController, animated: true) } } // MARK: UICloudSharingControllerDelegate // -------------------------------------- func cloudSharingController(_ csc: UICloudSharingController, failedToSaveShareWithError error: Error) { print("Failed to share to cloud: \(error)") } func itemTitle(for csc: UICloudSharingController) -> String? { return "Please join rootRecord share." } func cloudSharingControllerDidStopSharing(_ csc: UICloudSharingController) { print("Cloudkit stopped sharing") } func cloudSharingControllerDidSaveShare(_ csc: UICloudSharingController) { print("Cloudkit started sharing rootRecord") } 2