CloudKit - 无法使用我自己的 CKRecord.ID 修改现有的 CKRecord,即使删除有效
CloudKit - Failed to modify existing CKRecord with my own CKRecord.ID, even though delete works
对于我保存到CloudKit的每条记录,我传入一个CKRecord.ID,它是使用我自己的UUID制作的,如下所示:
let recordId = CKRecord.ID(recordName: myOwnUUID, zoneID: .default)
let record = CKRecord(recordType: recordType, recordID: recordId)
record.setValue(title, forKey: "title")
...
UUID 是我的数据模型的一部分,不会针对每条记录更改。
我能够成功删除记录,再次传入相同的CKRecord.ID:
func delete(_ item: MyItem, completion: @escaping (Result<Int, Error>) -> ()) {
let myOwnUUID = item.id // this is the exact same UUID that I used to create/save the record the first time.
let recordId = CKRecord.ID(recordName: myOwnUUID, zoneID: .default)
ckDatabase.delete(withRecordID: recordId) { (recordId, error) in
DispatchQueue.main.async {
if let error = error {
completion(.failure(error))
return
}
guard recordId != nil else {
completion(.failure(CloudKitHelperError.castFailure))
return
}
completion(.success(0))
}
}
}
所以,删除作品没有任何问题。
但是当我尝试 修改 记录时,我收到错误消息:"Server Record Changed"
... "record to insert already exists"
:
<CKError 0x600000b82af0: "Partial Failure" (2/1011); "Failed to modify
some records"; uuid = 9A077F5D-AB44-412C-9B87-BFBAE3C7B19B; container
ID = "iCloud.com.xxx.yyy"; partial errors: {
CC0A0279-F511-4EF4-BF89-4A3072EA1AEF:(_defaultZone:defaultOwner)
= <CKError 0x600000b80240: "Server Record Changed" (14/2004); server message = "record to insert already exists"; uuid =
9A077F5D-AB44-412C-9B87-BFBAE3C7B19B> }>
这是我的修改代码:
func modify(_ item: MyItem, completion: @escaping (Result<Int, Error>) -> ()) {
let myOwnUUID = item.id // this is the exact same UUID that I used to create/save the record the first time.
let recordId = CKRecord.ID(recordName: myOwnUUID, zoneID: .default)
let record = CKRecord(recordType: recordType, recordID: recordId)
record.setObject(item.title as __CKRecordObjCValue, forKey: "title")
let configuration = CKOperation.Configuration()
configuration.timeoutIntervalForRequest = 10
configuration.timeoutIntervalForResource = 10
let operation = CKModifyRecordsOperation(recordsToSave: [record], recordIDsToDelete: nil)
operation.configuration = configuration
operation.modifyRecordsCompletionBlock = { (savedRecords, _, error) in
DispatchQueue.main.async {
if savedRecords != nil, error == nil {
completion(.success(0))
}
if let error = error {
completion(.failure(error))
}
}
}
ckDatabase.add(operation)
}
顺便说一句,ckDatabase
设置为:ckDatabase = CKContainer(identifier: "iCloud.com.xxx.yyy").privateCloudDatabase
。
那么,为什么我不能使用创建记录时使用的 CKRecord.ID 修改现有记录?删除操作清晰识别。
一般来说,您应该始终从后端获取 CKRecord
对象,而不是在内存中构造它。只有这样,cloudkit 才能正确初始化它。
首先给你这条记录的代码在哪里,而不是下面的代码?
let record = CKRecord(recordType: recordType, recordID: recordId)
(可选)检查 record save policy。
详情,see this answer.
对于我保存到CloudKit的每条记录,我传入一个CKRecord.ID,它是使用我自己的UUID制作的,如下所示:
let recordId = CKRecord.ID(recordName: myOwnUUID, zoneID: .default)
let record = CKRecord(recordType: recordType, recordID: recordId)
record.setValue(title, forKey: "title")
...
UUID 是我的数据模型的一部分,不会针对每条记录更改。
我能够成功删除记录,再次传入相同的CKRecord.ID:
func delete(_ item: MyItem, completion: @escaping (Result<Int, Error>) -> ()) {
let myOwnUUID = item.id // this is the exact same UUID that I used to create/save the record the first time.
let recordId = CKRecord.ID(recordName: myOwnUUID, zoneID: .default)
ckDatabase.delete(withRecordID: recordId) { (recordId, error) in
DispatchQueue.main.async {
if let error = error {
completion(.failure(error))
return
}
guard recordId != nil else {
completion(.failure(CloudKitHelperError.castFailure))
return
}
completion(.success(0))
}
}
}
所以,删除作品没有任何问题。
但是当我尝试 修改 记录时,我收到错误消息:"Server Record Changed"
... "record to insert already exists"
:
<CKError 0x600000b82af0: "Partial Failure" (2/1011); "Failed to modify some records"; uuid = 9A077F5D-AB44-412C-9B87-BFBAE3C7B19B; container ID = "iCloud.com.xxx.yyy"; partial errors: { CC0A0279-F511-4EF4-BF89-4A3072EA1AEF:(_defaultZone:defaultOwner) = <CKError 0x600000b80240: "Server Record Changed" (14/2004); server message = "record to insert already exists"; uuid = 9A077F5D-AB44-412C-9B87-BFBAE3C7B19B> }>
这是我的修改代码:
func modify(_ item: MyItem, completion: @escaping (Result<Int, Error>) -> ()) {
let myOwnUUID = item.id // this is the exact same UUID that I used to create/save the record the first time.
let recordId = CKRecord.ID(recordName: myOwnUUID, zoneID: .default)
let record = CKRecord(recordType: recordType, recordID: recordId)
record.setObject(item.title as __CKRecordObjCValue, forKey: "title")
let configuration = CKOperation.Configuration()
configuration.timeoutIntervalForRequest = 10
configuration.timeoutIntervalForResource = 10
let operation = CKModifyRecordsOperation(recordsToSave: [record], recordIDsToDelete: nil)
operation.configuration = configuration
operation.modifyRecordsCompletionBlock = { (savedRecords, _, error) in
DispatchQueue.main.async {
if savedRecords != nil, error == nil {
completion(.success(0))
}
if let error = error {
completion(.failure(error))
}
}
}
ckDatabase.add(operation)
}
顺便说一句,ckDatabase
设置为:ckDatabase = CKContainer(identifier: "iCloud.com.xxx.yyy").privateCloudDatabase
。
那么,为什么我不能使用创建记录时使用的 CKRecord.ID 修改现有记录?删除操作清晰识别。
一般来说,您应该始终从后端获取 CKRecord
对象,而不是在内存中构造它。只有这样,cloudkit 才能正确初始化它。
首先给你这条记录的代码在哪里,而不是下面的代码?
let record = CKRecord(recordType: recordType, recordID: recordId)
(可选)检查 record save policy。
详情,see this answer.