首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何(以及何时)在CKRecord上使用iCloud的CKRecord方法?

如何(以及何时)在CKRecord上使用iCloud的CKRecord方法?
EN

Stack Overflow用户
提问于 2016-09-28 02:41:41
回答 2查看 2.3K关注 0票数 19

当我将记录保存在本地的数据库中时,应该使用encodeSystemFields

导出数据后,在反序列化数据时必须做什么特殊的事情吗?

我应该根据该数据中的信息来执行哪些方案?

作为一种变化(如果前面的问题中没有提到),这些信息对我有什么帮助呢?(我认为数据损坏)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-28 04:22:50

encodeSystemFields对于避免再次从CloudKit获取一个CKRecord来更新它很有用(除非记录冲突)。

这样做的目的是:

当存储从CloudKit检索的记录的数据时(例如,通过CKFetchRecordZoneChangesOperation检索到本地存储的记录更改同步):

1.)将CKRecord存档到NSData:

代码语言:javascript
复制
let record = ...

// archive CKRecord to NSData
let archivedData = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWithMutableData: archivedData)
archiver.requiresSecureCoding = true
record.encodeSystemFieldsWithCoder(with: archiver)
archiver.finishEncoding()

2.)在本地存储与本地记录关联的archivedData (例如,在数据库中)。

当您希望将对本地记录所做的更改保存回CloudKit

1.)从存储的CKRecord中解压缩NSData:

代码语言:javascript
复制
let archivedData = ... // TODO: retrieved from your local store

// unarchive CKRecord from NSData
let unarchiver = NSKeyedUnarchiver(forReadingWithData: archivedData)  
unarchiver.requiresSecureCoding = true 
let record = CKRecord(coder: unarchiver)

2.)使用未存档的记录作为更改的基础。(即在其上设置更改的值)

代码语言:javascript
复制
record["City"] = "newCity"

3.)通过CloudKit将记录保存到CKModifyRecordsOperation。

为什么?

来自苹果:

本地存储记录 如果将记录存储在本地数据库中,请使用encodeSystemFields(with:)方法对记录的元数据进行编码和存储。元数据包含记录ID和更改标记,稍后需要这些标记将本地数据库中的记录与CloudKit.存储的记录同步。

将更改保存到CKRecord的CloudKit中时,需要将更改保存到服务器的记录中。

您不能只使用相同的CKRecord创建一个新的recordID,设置其上的值并保存它。如果这样做,您将收到一个“服务器记录更改”错误--在本例中,这是因为现有的服务器记录包含本地记录(从零开始创建)缺少的元数据。

因此,您有两个解决方案:

  1. 从CKRecord请求CloudKit (使用recordID),对该CKRecord进行更改,然后将其保存回CloudKit。
  2. 使用encodeSystemFields,并在本地存储元数据,将其解压缩以创建一个“基本”CKRecord,该CKRecord具有将更改保存到所述CKRecord回CloudKit的所有适当元数据。

第二,节省你的网络往返*。

*假设另一台设备在此期间没有修改记录--这也是这些数据帮助您防范的。如果另一个设备在上次检索记录的时间和尝试保存记录的时间之间修改记录,CloudKit将(默认情况下)用“服务器记录更改”拒绝记录保存尝试。这是您以适合应用程序和数据模型的方式执行冲突解决的线索。(通常是从CloudKit中获取新的服务器记录,并在再次尝试保存之前对该CKRecord重新应用适当的值更改。)

注意:当您将更新的CKRecord保存/从CloudKit保存/检索时,您必须记住更新本地存储的归档CKRecord。

票数 41
EN

Stack Overflow用户

发布于 2021-11-03 16:02:39

从iOS 15 /SWIFT5.5开始,这个扩展可能会有帮助:

代码语言:javascript
复制
public extension CKRecord {
    var systemFieldsData: Data {
        let archiver = NSKeyedArchiver(requiringSecureCoding: true)
        encodeSystemFields(with: archiver)
        archiver.finishEncoding()
        return archiver.encodedData
    }

    convenience init?(systemFieldsData: Data) {
        guard let una = try? NSKeyedUnarchiver(forReadingFrom: systemFieldsData) else {
            return nil
        }
        self.init(coder: una)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39737190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档