Swift CloudKit SaveRecord “Error saving record”

后端 未结 3 1203
有刺的猬
有刺的猬 2021-01-30 18:52

I am trying to save a record to CloudKit but am getting an error. I had seen elsewhere that this was an issue that required knowing how to save but I can\'t get this to work.

3条回答
  •  没有蜡笔的小新
    2021-01-30 19:33

    A record can be saved to iCloud using CKDatabase's convenience method saveRecord: or via a CKModifyRecordsOperation. If it's a single record, you can use saveRecord: but will need to fetch the record you'd like to modify using fetchRecordWithID: prior to saving it back to iCloud. Otherwise, it will only let you save a record with a new RecordID. More here.

    database.fetchRecordWithID(recordId, completionHandler: { record, error in
        if let fetchError = error {
                println("An error occurred in \(fetchError)")
            } else {
                // Modify the record
                record.setObject(newName, forKey: "name")
            } 
    }
    
    
    database.saveRecord(aRecord, completionHandler: { record, error in
        if let saveError = error {
                println("An error occurred in \(saveError)")
            } else {
                // Saved record
            } 
    }
    

    The code above is only directionally correct but won't work as is because by the time the completionHandler of fetchRecordWithID returns, saveRecord will have fired already. A simple solution would be to nest saveRecord in the completionHandler of fetchRecordWithID. A probably better solution would be to wrap each call in a NSBlockOperation and add them to an NSOperationQueue with saveOperation dependent on fetchOperation.

    This part of your code would be for a CKModifyRecordsOperation and not needed in case you are only updating a single record:

    var ops:CKModifyRecordsOperation = CKModifyRecordsOperation()
    ops.savePolicy = CKRecordSavePolicy.IfServerRecordUnchanged
    database.addOperation(ops)
    

    If you do use a CKModifyRecordsOperation instead, you'll also need to set at least one completion block and deal with errors when conflicts are detected with existing records:

    let saveRecordsOperation = CKModifyRecordsOperation()
    
    var ckRecordsArray = [CKRecord]()
    // set values to ckRecordsArray
    
    saveRecordsOperation.recordsToSave = ckRecordsArray
    saveRecordsOperation.savePolicy = .IfServerRecordUnchanged
    saveRecordsOperation.perRecordCompletionBlock { record, error in
        // deal with conflicts
        // set completionHandler of wrapper operation if it's the case
    }
    
    saveRecordsOperation.modifyRecordsCompletionBlock { savedRecords, deletedRecordIDs, error in
        // deal with conflicts
        // set completionHandler of wrapper operation if it's the case
    }
    
    database.addOperation(saveRecordsOperation)
    

    There isn't much sample code yet besides the CloudKitAtlas demo app, which is in Objective-C. Hope this helps.

提交回复
热议问题