服务器记录中的 CKAsset 不包含 fileURL,甚至无法检查 nil

Posted

技术标签:

【中文标题】服务器记录中的 CKAsset 不包含 fileURL,甚至无法检查 nil【英文标题】:CKAsset in server record contains no fileURL, cannot even check for nil 【发布时间】:2016-12-10 05:29:56 【问题描述】:

当我使用CKModifyRecordsOperation.IfServerRecordUnchanged 保存策略保存包含CKAsset(只是JPG 图像)的记录时,我正在测试同步冲突。我收到错误CKErrorCode.ServerRecordChanged。这个CKError返回给我解决冲突的有用信息,包括我试图保存的CKRecord,以及记录的当前服务器版本。第一个在error.userInfo[CKRecordChangedErrorClientRecordKey],第二个在error.userInfo[CKRecordChangedErrorServerRecordKey]

我的问题是我正在尝试使用以下代码访问服务器记录的 CKAsset:

if let photoAsset = rec["myPhoto"] as? CKAsset 
  print("PhotoAsset.fileURL: \(photoAsset.fileURL)")  // BAD_ACCESS ERROR HERE
  self.myPartner.photo = NSData(contentsOfURL: photoAsset.fileURL)

我不明白这怎么可能。但经过进一步调查,我打印出客户端和服务器 CKRecords 并且服务器缺少“路径”属性。

客户端CKAsset...myPhoto(修改)-> CKAsset:0x7b960d90;路径=〜/ TMP / BF185B2C-7A39-4730-9530-9797E843243Aphoto,大小= 373959,uploadRank = 0,uploadReceipt = A92Eg1qoyPG7yrg3,UUID = 3C2D5DC8-4FF5-4A81-853B-395FC1C59862,referenceSignature = , flags=uploaded, WrappedEncryptionKey=, signature=

服务器 CKAsset...myPhoto = CKAsset: 0x7be700d0; referenceSignature = ,大小= 373959,uploadRank = 0,UUID = DF5D2EB4-033C-49A2-AF52-6055B5A44106,wrappedEncryptionKey = ,签名=

注意path=~/tmp/C706423B-A3E8-4051-A9B3-483C718BFBF5photo 是如何从服务器一中丢失的?谁能解释一下?为了解决这个问题,我尽量避免接触服务器记录中的 CKAsset。我希望至少能够检查零。我想把它放在那里以防它帮助其他人。

【问题讨论】:

运气好能找到这个问题的解释吗?我有同样的问题,但仅适用于 ios 9,在 iOS 10 上它适用于我。通过 CloudKit 同步资产会在所有 iOS 9 设备上崩溃。仅供参考:我使用的是 Swift 3.0。 我也有同样的问题。打开服务器记录时,CKAsset.fileUrl 为 nil。 iOS12.1.2,Xcode 10.2.1。 【参考方案1】:

由于访问fileURL 时崩溃,这很可能是一个框架错误。可能是因为 CKRecord 被埋在字典里的疏忽。我只是用普通的fetch(withRecordID:) 跟进它。

【讨论】:

【参考方案2】:

CKRecord 中的serverRecord 属性访问CKAsset 时,我在iOS 11.2.1 上也遇到了这个问题。这有点令人沮丧。一种解决方法是通过func fetch(withRecordID... 再次获取对象,然后访问fileURL

【讨论】:

【参考方案3】:

这似乎是正确的行为,而不是错误。

CloudKit 通知您,您的 write 操作失败,因为您没有使用最新的 CKRecord,并为您提供了服务器当前 CKRecord 的非水合版本,因此您可以确定哪些字段不同于你的出发点。剩下的就看你自己了。

如果 CloudKit 在写入操作的错误响应中返回完全水合的服务器记录,则可能会浪费大量带宽/资源。

这就是 CKAsset 存在的原因:将与 CKRecord 关联的大小受限的键值字段与可以附加到它们的无限大小的二进制资产分开。

【讨论】:

以上是关于服务器记录中的 CKAsset 不包含 fileURL,甚至无法检查 nil的主要内容,如果未能解决你的问题,请参考以下文章

CKAsset 获取 PDF 并呈现在 UIWebView Swift3 中

将 CloudKit 记录保存到本地文件保存除 CKAsset 之外的所有字段

所有 CKAsset 在所有设备上都可用?

Swift 3 使用 CKAsset 将图像发送到 CloudKit

长期运行的 CKAsset 上传错误

如何使用 CKSubscription 检查 CKAsset 更改?