如何使用 Cloudkit 将字典(或任何其他复杂结构)保存到 iCloud 中?

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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]]

【讨论】:

以上是关于如何使用 Cloudkit 将字典(或任何其他复杂结构)保存到 iCloud 中?的主要内容,如果未能解决你的问题,请参考以下文章

CloudKit,NSPredicate在私有容器中返回计数或确定是否存在任何记录?

如何允许任何用户在 cloudkit 仪表板中预览其数据库?

用户可以编辑 CloudKit 数据吗?

如何获取 CloudKit 的实际配额?

使用 NSPredicate 查询 CloudKit 以获取空白(或 null 或其他)的日期

将 Cloudkit 资产用作 UIimage