Swift   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了swift – Codable到CKRecord大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我有几个可编码的结构,我想创建一个通用协议,将它们编码为CKRecord for CloudKit并进行解码. 我有一个Encodable的扩展来创建一个字典: extension Encodable { var Dictionary: [String: Any] { return (try? JSONserialization.jsonObject(with: JSON
我有几个可编码的结构,我想创建一个通用协议,将它们编码为CKRecord for CloudKit并进行解码.

我有一个Encodable的扩展来创建一个字典:

extension Encodable {

    var Dictionary: [String: Any] {
        return (try? JSONserialization.jsonObject(with: JSONEncoder().encode(self),options: .allowFragments)) as? [String: Any] ?? [:]
    }
}

然后在协议扩展中,我将记录创建为属性,如果类型为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
}

要解码:

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 }
}

除数据类型外,所有内容都可以正常工作.它无法从字典中识别出来.所以,我无法将其转换为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
}

针对更复杂案例的另一个解决方案是使用一些第三方库,我遇到的是:https://github.com/insidegui/CloudKitCodable

大佬总结

以上是大佬教程为你收集整理的swift – Codable到CKRecord全部内容,希望文章能够帮你解决swift – Codable到CKRecord所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。