【问题标题】:Return Bool from CloudKit Save CompletionHandler Not Correct从 CloudKit 返回 Bool 保存 CompletionHandler 不正确
【发布时间】:2018-01-13 00:07:06
【问题描述】:

我正在创建一个将记录保存到 CloudKit 并将数据本地存储在 Core Data 中的应用程序。我确实可以在这两个位置保存记录,但是当与 iCloud 的连接不可用或存在保存错误时,我需要能够处理错误。我以为我可以在 CKModifyRecordsOperation 完成块中填充一个变量来区分,但这不起作用 - CloudKit 保存的返回值始终为 false,即使过程成功。想法是先保存到 CloudKit,然后检索 recordID 并使用 Core Data 保存。

这是我的代码,我从条形按钮调用doTheComboSave()。控制台输出位于代码下方。任何意见,将不胜感激。 Xcode 8.3.3、Swift 3、iOS 10。

func saveNewCloudKitRecord() -> Bool {

    privateDatabase = container().privateCloudDatabase
    recordZone = CKRecordZone(zoneName: "myPatientZone")

    var blockSavedToCloudKit = false

    let myRecord = CKRecord(recordType: "Patient", zoneID: (recordZone?.zoneID)!)
    myRecord.setObject(firstNameTextField.text as CKRecordValue?, forKey: "firstname")
    myRecord.setObject(lastNameTextField.text as CKRecordValue?, forKey: "lastname")
    let parentRefID = CKRecordID(recordName: "047EBE6C-AB1C-0183-8D80-33C0E4AE228B", zoneID: (recordZone?.zoneID)!)
            //
    //bunch more record fields
    //

    let modifyRecordsOperation = CKModifyRecordsOperation(recordsToSave: [myRecord], recordIDsToDelete: nil)
    modifyRecordsOperation.timeoutIntervalForRequest = 10
    modifyRecordsOperation.timeoutIntervalForResource = 10

    modifyRecordsOperation.modifyRecordsCompletionBlock = {

        records, recordIDs, error in

        if let err = error {
            blockSavedToCloudKit = false
            //create placeholder record name for later updating
        } else {
            blockSavedToCloudKit = true
            self.currentRecord = myRecord
            self.passedInCKRecord = myRecord
        }//if err

    }//modifyRecordsOperation

    privateDatabase?.add(modifyRecordsOperation)

    print("blockSavedToCloudKit is \(blockSavedToCloudKit)")
    return blockSavedToCloudKit

}//saveNewCloudKitRecord


typealias SavedCompletion = (_ success:Bool) -> Void

func saveTwoFiles(completionHandler : SavedCompletion) {

    let flag = saveNewCloudKitRecord()
    print("flag is \(flag)")

    completionHandler(flag)
    print("completionHandler(flag) is \(flag)")
}//makeTheComboSave

func doTheComboSave() {

    saveTwoFiles() { (success) -> Void in

        print("saveTwoFiles is \(success)")

        if success {
            //will pass the CKRecord so core data can store the recordID and recordName
            saveTheNewRecord()//this is the Core Data save

            DispatchQueue.main.async {
                self.performSegue(withIdentifier: "unwindToMasterViewController", sender: self)
                print("Completion block has been run successfully.")
            }//Dispatch

        } else {
            //create placeholder recordName for later updating
            saveTheNewRecord()//this is the Core Data save
            DispatchQueue.main.async {
                self.performSegue(withIdentifier: "unwindToMasterViewController", sender: self)
                print("Completion block has been run but the file save to CloudKit failed.")
            }//Dispatch


        }//if else
    }//block

}//doTheComboSave

控制台输出:

blockSavedToCloudKit 为假

标志为假

saveTwoFiles 是假的

completionHandler(flag) 为假

完成块已运行,但文件保存到 CloudKit 失败。

修改记录操作成功

currentRecordName 是:B53DCFB8-0EFB-4E79-8762-FECCEFBA9BD8

【问题讨论】:

  • 我认为您不了解 CloudKit/网络调用的异步性质。 saveNewCloudKitRecord 返回的 false 在操作完成之前返回。您将需要一个屏障或信号量来使其返回您在示例中所期望的方式。

标签: ios swift cloudkit completionhandler


【解决方案1】:

请参阅上面 Ichydon 的评论。

saveNewCloudKitRecord() 函数在 completionHandler 设置我想要使用的布尔值之前返回。整个想法是首先创建 CloudKit 记录,以便我可以检索记录名称以存储在 Core Data 中,以便同步本地和云记录。

更好的方法是先保存到 Core Data,然后自己创建 CKRecordID 并在保存到 CloudKit 时将其提供给记录。

在保存Core Data记录的函数中:

let myRecordName = UUID().uuidString

然后返回该字符串以用作 CloudKit 保存的参数。

let myRecordID : CKRecordID = CKRecordID(recordName: myRecordName, zoneID: (recordZone?.zoneID)!)

let myRecord = CKRecord(recordType: "Whatever", recordID : myRecordID)

希望这对其他人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 2021-06-29
    相关资源
    最近更新 更多