问题描述
我需要将日期绑定到值并将其保存到Cloudkit中。我宁愿CKRecord
是一个字典数组:[[date,value)],而不是只为每个对象和下标“ date”和“ value”保存一个新的CKRecord
。我环顾四周,找不到此类Cloudkit数据存储的任何示例。我本来会以为Codable应该已经桥接到Cloudkit了,但是我看不到任何指示。有一个library处理此问题,但不处理这种类型的嵌套。反正有这样做吗?
解决方法
尽管CKRecord
确实具有支持Array
的能力,但它主要用于存储简单的数据类型,例如字符串,数字和CKRecord.Reference
。您没有明确指出“值”类型是什么,但这是一个使用JSONEncoder
/ JSONDecoder
来增加对写入或读取任何可编码类型到CKRecord
的支持的示例。编码器/解码器仅将Encodable
/ Decodable
类型转换为二进制Data
表示形式,CKRecord
也支持二进制表示形式。
private let encoder: JSONEncoder = .init()
private let decoder: JSONDecoder = .init()
extension CKRecord {
func decode<T>(forKey key: FieldKey) throws -> T where T: Decodable {
guard let data = self[key] as? Data else {
throw CocoaError(.coderValueNotFound)
}
return try decoder.decode(T.self,from: data)
}
func encode<T>(_ encodable: T,forKey key: FieldKey) throws where T: Encodable {
self[key] = try encoder.encode(collection)
}
}
用法如下:
let collection: [[Date: String]] = [[:]]
let record = CKRecord(recordType: "MyRecord")
try? record.encode(collection,forKey: "collection")
let persisted = try? record.decode(forKey: "collection") as [[Date: String]]