一般来说,您有 unitary 方法(如 saveRecord),它一次只处理一条记录,以及 大量操作(像CKModifyRecordsOperation),同时处理多条记录。
这些保存操作可用于保存 记录,或更新 记录(即获取它们,对其应用更改,然后再次保存)。
保存示例:
您创建了一条记录并希望将其保存到 CloudKit DB:
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
// just an example of how you could create an array of CKRecord
// this "map" method in Swift is so useful
var records = anArrayOfObjectsConvertibleToRecords.map { $0.recordFromObject }
var uploadOperation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
uploadOperation.savePolicy = .IfServerRecordUnchanged // default
uploadOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordsIDs, error in
if error != nil {
println("Error saving records: \(error.localizedDescription)")
} else {
println("Successfully saved records")
}
}
database.addOperation(uploadOperation)
更新示例:
通常,您有 3 种情况需要更新记录:
- 您知道记录标识符(通常是您要保存的记录的recordID.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 {
// Now you have grabbed your existing record from iCloud
// Apply whatever changes you want
record.setObject(aValue, forKey: attributeToChange)
// Save this record again
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 // better be accurate to get only the record you need
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
// Now you have grabbed your existing record from iCloud
// Apply whatever changes you want
record.setObject(aValue, forKey: attributeToChange)
// Save this record again
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 // can be NSPredicate(value: true) if you want them all
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 {
// Now you have grabbed an array of CKRecord from iCloud
// Apply whatever changes you want
for record in records {
record.setObject(aValue, forKey: attributeToChange)
}
// Save all the records in one batch
var saveOperation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
saveOperation.savePolicy = .IfServerRecordUnchanged // default
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,那么您肯定会收到错误。