我正在尝试将记录保存到 CloudKit 但出现错误。我在别处看到这是一个需要知道如何保存的问题,但我无法解决这个问题。
var database:CKDatabase = CKContainer.defaultContainer().publicCloudDatabase
var aRecord:CKRecord!
if self.cloudId == nil {
var recordId:CKRecordID = CKRecordID(recordName: "RecordId")
self.cloudId = recordId // Setup at top
}
aRecord = CKRecord(recordType: "RecordType", recordID: self.cloudId)
aRecord.setObject(self.localId, forKey: "localId")
// Set the normal names etc
aRecord.setObject(self.name, forKey: "name")
var ops:CKModifyRecordsOperation = CKModifyRecordsOperation()
ops.savePolicy = CKRecordSavePolicy.IfServerRecordUnchanged
database.addOperation(ops)
database.saveRecord(aRecord, completionHandler: { (record, error) in
if error != nil {
println("There was an error \(error.description)!")
} else {
var theRecord:CKRecord = record as CKRecord
self.cloudId = theRecord.recordID
}
})
这给了我错误:
There was an error <CKError 0x16d963e0: "Server Record Changed" (14/2017); "Error saving record <CKRecordID: 0x15651730; xxxxxx:(_defaultZone:__defaultOwner__)> to server: (null)"; uuid = 369226C6-3FAF-418D-A346-49071D3DD70A; container ID = "iCloud.com.xxxxx.xxxx-2">!
不确定,因为我已经添加了 CKModifyRecordsOperation。遗憾的是,Apple 的文档中没有示例。我想念那个(你在 MSDN 上得到的)。
谢谢大家!
最佳答案
可以使用 CKDatabase 的便捷方法 saveRecord:
或通过 CKModifyRecordsOperation 将记录保存到 iCloud。如果它是单个记录,您可以使用 saveRecord:
,但在将其保存回 iCloud 之前需要使用 fetchRecordWithID:
获取您要修改的记录。否则,它只会让你用新的 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
}
}
上面的代码只是方向正确,但不会按原样工作,因为在 fetchRecordWithID 的 completionHandler 返回时,saveRecord 已经触发。一个简单的解决方案是将 saveRecord 嵌套在 fetchRecordWithID 的 completionHandler 中。一个可能更好的解决方案是将每个调用包装在一个 NSBlockOperation
中,并将它们添加到一个 NSOperationQueue 中,saveOperation 依赖于 fetchOperation。
这部分代码用于 CKModifyRecordsOperation
,如果您只更新一条记录则不需要:
var ops:CKModifyRecordsOperation = CKModifyRecordsOperation()
ops.savePolicy = CKRecordSavePolicy.IfServerRecordUnchanged
database.addOperation(ops)
如果您确实使用 CKModifyRecordsOperation
,您还需要设置至少一个完成 block 并在检测到与现有记录的冲突时处理错误:
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)
除了使用 Objective-C 的 CloudKitAtlas 演示应用程序之外,还没有太多示例代码。希望这会有所帮助。
关于ios - Swift CloudKit 保存记录 "Error saving record",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24600308/