通常情况下,您有像saveRecord这样只处理一个记录的 单个操作 方法,以及像CKModifyRecordsOperation这样处理多个记录的 批量操作 方法。
这些保存操作可用于保存记录,也可用于更新记录(即获取它们、对它们进行更改,然后再次保存它们)。
保存示例:
您创建了一条记录并希望将其保存到 CloudKit 数据库:
let database = CKContainer.defaultContainer().publicCloudDatabase
var record = CKRecord(recordType: "YourRecordType")
database.saveRecord(record, completionHandler: { (savedRecord, saveError in
if saveError != nil {
println("Error saving record: \(saveError.localizedDescription)")
} else {
println("Successfully saved record!")
}
})
您创建了一堆记录并希望一次性保存它们:
let database = CKContainer.defaultContainer().publicCloudDatabase
var records = anArrayOfObjectsConvertibleToRecords.map { $0.recordFromObject }
var uploadOperation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
uploadOperation.savePolicy = .IfServerRecordUnchanged
uploadOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordsIDs, error in
if error != nil {
println("Error saving records: \(error.localizedDescription)")
} else {
println("Successfully saved records")
}
}
database.addOperation(uploadOperation)
更新示例:
通常,您有三种情况需要更新记录:
- 您知道要保存的记录的标识符(通常是要保存的记录ID.recordName):在这种情况下,
您将使用方法fetchRecordWithID,然后使用saveRecord方法
您知道有一个唯一的记录需要更新,但您不知道其记录ID:在这种情况下,您将使用带有方法的查询
performQuery,选择您需要的(唯一)记录,然后再次saveRecord
您正在处理需要更新的多个记录:在这种情况下,您将使用查询来获取所有记录
(performQuery),并使用CKModifyRecordsOperation来保存它们。
情况 1 - 您知道要更新的记录的唯一标识符:
let myRecordName = aUniqueIdentifierForMyRecord
let recordID = CKRecordID(recordName: myRecordName)
database.fetchRecordWithID(recordID, completionHandler: { (record, error) in
if error != nil {
println("Error fetching record: \(error.localizedDescription)")
} else {
record.setObject(aValue, forKey: attributeToChange)
database.saveRecord(record, completionHandler: { (savedRecord, saveError) in
if saveError != nil {
println("Error saving record: \(saveError.localizedDescription)")
} else {
println("Successfully updated record!")
}
})
}
})
情况2 - 您知道存在与您条件相对应的记录,并且您想要更新它:
let predicate = yourPredicate
var query = CKQuery(recordType: YourRecordType, predicate: predicate)
database.performQuery(query, inZoneWithID: nil, completionHandler: { (records, error) in
if error != nil {
println("Error querying records: \(error.localizedDescription)")
} else {
if records.count > 0 {
let record = records.first as! CKRecord
record.setObject(aValue, forKey: attributeToChange)
database.saveRecord(record, completionHandler: { (savedRecord, saveError in
if saveError != nil {
println("Error saving record: \(saveError.localizedDescription)")
} else {
println("Successfully updated record!")
}
})
}
}
})
第3种情况 - 您想一次性获取多条记录并将它们全部更新:
let predicate = yourPredicate
var query = CKQuery(recordType: YourRecordType, predicate: predicate)
database.performQuery(query, inZoneWithID: nil, completionHandler: { (records, error) in
if error != nil {
println("Error querying records: \(error.localizedDescription)")
} else {
for record in records {
record.setObject(aValue, forKey: attributeToChange)
}
var saveOperation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
saveOperation.savePolicy = .IfServerRecordUnchanged
saveOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordsIDs, error in
if error != nil {
println("Error saving records: \(error.localizedDescription)")
} else {
println("Successfully updated all the records")
}
}
database.addOperation(saveOperation)
}
})
这是对你问题的详细回答,但是你的代码将单元保存方法和CKModifyRecordsOperation混合在一起了。
此外,你必须要知道每次创建CKRecord时,CloudKit都会为其分配一个唯一标识符(record.recordID.recordName),除非你自己提供一个。因此,在调用所有这些优秀的方法之前,你必须知道是想要获取现有记录还是创建新记录:-)
如果尝试使用与另一个记录相同的唯一标识符创建新的CKRecord,则很可能会出现错误。
recordChangeTag
吗?这样你就可以避免调用fetchRecordWithID
,从而减少周转时间。 - János