云套件:使用CKModifyRecordsOperation保存记录时出错

4
<CKError 0x14d8cb70: "Partial Failure" (2/1011); "Failed to modify some records"; partial errors: {
    B5DEF0B5-F064-4B27-9C89-BE75C9134297:(_defaultZone:__defaultOwner__) = <CKError 0x14d83b70: "Server Record Changed" (14/2037); "Error saving record <CKRecordID: 0x15748cd0; B5DEF0B5-F064-4B27-9C89-BE75C9134297:(_defaultZone:__defaultOwner__)> to server: Protection data didn't match">
}>

当我尝试保存CKRecordCloudKit时,我遇到了这个错误。有什么想法吗?

我需要像常规API一样先获取记录吗?

我正在使用CKModifyRecordsOperation方法来更新更多的记录。

1个回答

7
当您计划进行更新时,首先需要读取记录,进行更改,然后再写入记录。在读取和写入记录之间的时间内,您收到了记录已更改的通知。
如果服务器上记录的版本比您尝试保存的版本更新,则服务器会返回CKErrorServerRecordChanged错误。错误对象的userInfo字典包含冲突记录的不同版本。使用这些键来检索记录,并执行必要的解决逻辑以解决冲突。
如下所述,在您的情况下,问题是将对象持久化到数据库中并重新创建CKRecord以进行修改。在这种情况下,您需要使用CKRecord encodeSystemFieldsWithCoder来持久化系统字段。通过使用NSCoder初始化CKRecord来重新创建CKRecord。您可以使用NSKeyedArchiver和NSKeyedUnarchiver保存CKRecord并重新创建它。如果需要示例,请参见https://github.com/evermeer/EVCloudKitDao/blob/master/AppMessage/AppMessage/CloudKit/EVCloudKitDao.swift底部的fromCKRecord和toCKRecord方法。

2
对于一个记录来说,这样做还好,但如果要更新100个记录,我必须先下载,找到需要修改的记录,然后再上传,这是很麻烦的吗?brbrbr - János
2
你可以使用 -[CKRecord encodeSystemFieldsWithCoder:] 来仅编码记录的系统字段(例如更改标签)。稍后,你可以解档仅包含系统字段的记录,仅应用要保存到服务器的更改,并保存记录。如果你已经在本地数据库中保存了记录,那么这样做可以避免向服务器发送额外的请求。 - farktronix
使用CKQueryOperation的"desired keys"属性在多大程度上可以缓解“更新数百条记录”的问题? - AmitaiB
@AmitaiB 即使您只更新了一个字段,记录也将被更新。更改令牌是针对整个记录的。因此,如果您仅检索了一半的字段并且更新在其他字段中,则仍将视记录为已更新,并且即使更改不在您的字段中,您也必须进行重新读取。 - Edwin Vermeer
那么它会节省空间(带宽、内存、存储),但不会节省时间。谢谢。 - AmitaiB
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接