【问题标题】:How to save a dictionary (or any other complex structure) into iCloud using Cloudkit?如何使用 Cloudkit 将字典(或任何其他复杂结构)保存到 iCloud 中?
【发布时间】:2020-08-20 13:07:16
【问题描述】:

我需要将日期绑定到一个值并将其保存到 Cloudkit。与其为每个对象和下标“日期”和“值”保存一个新的CKRecord,我更希望CKRecord 是一个字典数组:[(日期,值)]。我环顾四周,找不到这种类型的 Cloudkit 数据存储的任何示例。到目前为止,我本以为 Codable 会被桥接到 Cloudkit,但我没有看到任何迹象表明这一点。有一个library 可以处理这个问题,但它不处理这种类型的嵌套。有没有办法做到这一点?

【问题讨论】:

    标签: ios swift icloud cloudkit ckrecord


    【解决方案1】:

    虽然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]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      • 2021-12-10
      相关资源
      最近更新 更多