CloudKit:使用 CKModifyRecordsOperation 保存记录时出错

Posted

技术标签:

【中文标题】CloudKit:使用 CKModifyRecordsOperation 保存记录时出错【英文标题】:CloudKit: Error saving record with CKModifyRecordsOperation 【发布时间】:2015-04-14 20:43:28 【问题描述】:
<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">
>

我在尝试将CKRecords 保存到CloudKit 时收到此错误。有什么想法吗?

我必须像在便利 API 中那样获取第一条记录吗?

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

【问题讨论】:

【参考方案1】:

当您计划进行更新时,您首先需要读取记录,进行更改,然后写入记录。您收到一条通知,指出在读取和写入记录之间记录发生了更改。

如果服务器上记录的版本比您尝试保存的版本新,服务器会返回 CKErrorServerRecordChanged 错误。错误对象的 userInfo 字典包含不同版本的冲突记录。使用这些键检索记录并执行解决冲突所需的任何解决逻辑。

正如下面在您的案例中所讨论的,问题是您将对象保存到数据库并重新创建了 CKRecord 来进行修改。在这种情况下,您需要使用 CKRecord encodeSystemFieldsWithCoder 来保存系统字段。并通过使用 NSCoder 对其进行初始化来重新创建 CKRecord。您可以使用 NSKeyedArchiver 和 NSKeyedUnarchiver 来保存 CKRecord 并重新创建它。需要样例请看https://github.com/evermeer/EVCloudKitDao/blob/master/AppMessage/AppMessage/CloudKit/EVCloudKitDao.swift底部的fromCKRecord和toCKRecord方法

【讨论】:

1条记录是可以的,但是更新100条记录,严重吗我要先下载,找哪条修改,再上传?? brbrbr 您不必再阅读它们。请参阅我的更新答案。因此,只需将它们全部保存并在使用错误中的记录 ID 出现错误时再次尝试更新 您可以使用-[CKRecord encodeSystemFieldsWithCoder:] 仅对记录的系统字段(如更改标签)进行编码。您稍后可以仅使用系统字段取消归档记录,仅应用您希望保存到服务器的更改,然后保存记录。如果您已经保存了本地记录数据库,这应该可以节省您往返服务器的时间。 我照你说的做,(1) 阅读 (2) 修改 CKRecords (3) 保存,和我经常用某组记录来做,有时我只收到部分记录,而不是我在CKQuery的谓词中指定的条件,你知道为什么吗? CloudKit 返回的结果是有限的。记录的标准数量似乎是 100,但这可能会根据 iCloud 上的总负载情况而有所不同。如果您使用 SKQueryOperation,那么您可以通过设置 .resultsLimit 来影响需要返回的记录数。默认值为 CKQueryOperationMaximumResults

以上是关于CloudKit:使用 CKModifyRecordsOperation 保存记录时出错的主要内容,如果未能解决你的问题,请参考以下文章

CloudKit 设计建议

使用 CloudKit 修改数据

使用 CloudKit 延迟后触发推送通知

Swift 2 和 Cloudkit 的通知

CloudKit:删除记录的 CKQueryOperation

使用 CloudKit 共享时如何正确使用数据库订阅