Ale*_*nov 6 dictionary swift cloudkit codable
我有几个可编码的结构,我想创建一个通用协议,将它们编码为CKRecord for CloudKit并进行解码.
我有一个Encodable的扩展来创建一个字典:
extension Encodable {
var dictionary: [String: Any] {
return (try? JSONSerialization.jsonObject(with: JSONEncoder().encode(self), options: .allowFragments)) as? [String: Any] ?? [:]
}
}
Run Code Online (Sandbox Code Playgroud)
然后在协议扩展中,我将记录创建为属性,如果类型为Data,我尝试创建CKAsset.
var ckEncoded: CKRecord? {
// Convert self.id to CKRecord.name (CKRecordID)
guard let idString = self.id?.uuidString else { return nil }
let record = CKRecord(recordType: Self.entityType.rawValue,
recordID: CKRecordID(recordName: idString))
self.dictionary.forEach {
if let data = $0.value as? Data {
if let asset: CKAsset = try? ckAsset(from: data, id: idString) { record[$0.key] = asset }
} else {
record[$0.key] = $0.value as? CKRecordValue
}
}
return record
}
Run Code Online (Sandbox Code Playgroud)
要解码:
func decode(_ ckRecord: CKRecord) throws {
let keyIntersection = Set(self.dtoEncoded.dictionary.keys).intersection(ckRecord.allKeys())
var dictionary: [String: Any?] = [:]
keyIntersection.forEach {
if let asset = ckRecord[$0] as? CKAsset {
dictionary[$0] = try? self.data(from: asset)
} else {
dictionary[$0] = ckRecord[$0]
}
}
guard let data = try? JSONSerialization.data(withJSONObject: dictionary) else { throw Errors.LocalData.isCorrupted }
guard let dto = try? JSONDecoder().decode(self.DTO, from: data) else { throw Errors.LocalData.isCorrupted }
do { try decode(dto) }
catch { throw error }
}
Run Code Online (Sandbox Code Playgroud)
除数据类型外,所有内容都可以正常工作.它无法从字典中识别出来.所以,我无法将其转换为CKAsset.先感谢您.
我还发现到目前为止苹果还没有对此提供明确的支持。
我的解决方案是手动编码/解码:在我的 Codable 子类上,我添加了两个方法:
/// Returns CKRecord
func ckRecord() -> CKRecord {
let record = CKRecord(recordType: "MyClassType")
record["title"] = title as CKRecordValue
record["color"] = color as CKRecordValue
return record
}
init(withRecord record: CKRecord) {
title = record["title"] as? String ?? ""
color = record["color"] as? String ?? kDefaultColor
}
Run Code Online (Sandbox Code Playgroud)
对于更复杂的情况,另一种解决方案是使用一些第三方库,我遇到的一个是: https: //github.com/insidegui/CloudKitCodable
归档时间: |
|
查看次数: |
748 次 |
最近记录: |