当我将记录保存在本地的数据库中时,应该使用encodeSystemFields。
导出数据后,在反序列化数据时必须做什么特殊的事情吗?
我应该根据该数据中的信息来执行哪些方案?
作为一种变化(如果前面的问题中没有提到),这些信息对我有什么帮助呢?(我认为数据损坏)
发布于 2016-09-28 04:22:50
encodeSystemFields对于避免再次从CloudKit获取一个CKRecord来更新它很有用(除非记录冲突)。
这样做的目的是:
当存储从CloudKit检索的记录的数据时(例如,通过CKFetchRecordZoneChangesOperation检索到本地存储的记录更改同步):
1.)将CKRecord存档到NSData:
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:
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.)使用未存档的记录作为更改的基础。(即在其上设置更改的值)
record["City"] = "newCity"3.)通过CloudKit将记录保存到CKModifyRecordsOperation。
为什么?
来自苹果:
本地存储记录 如果将记录存储在本地数据库中,请使用encodeSystemFields(with:)方法对记录的元数据进行编码和存储。元数据包含记录ID和更改标记,稍后需要这些标记将本地数据库中的记录与CloudKit.存储的记录同步。
将更改保存到CKRecord的CloudKit中时,需要将更改保存到服务器的记录中。
您不能只使用相同的CKRecord创建一个新的recordID,设置其上的值并保存它。如果这样做,您将收到一个“服务器记录更改”错误--在本例中,这是因为现有的服务器记录包含本地记录(从零开始创建)缺少的元数据。
因此,您有两个解决方案:
第二,节省你的网络往返*。
*假设另一台设备在此期间没有修改记录--这也是这些数据帮助您防范的。如果另一个设备在上次检索记录的时间和尝试保存记录的时间之间修改记录,CloudKit将(默认情况下)用“服务器记录更改”拒绝记录保存尝试。这是您以适合应用程序和数据模型的方式执行冲突解决的线索。(通常是从CloudKit中获取新的服务器记录,并在再次尝试保存之前对该CKRecord重新应用适当的值更改。)
注意:当您将更新的CKRecord保存/从CloudKit保存/检索时,您必须记住更新本地存储的归档CKRecord。
发布于 2021-11-03 16:02:39
从iOS 15 /SWIFT5.5开始,这个扩展可能会有帮助:
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)
}
}https://stackoverflow.com/questions/39737190
复制相似问题