Swift 4.1可编码采用数组到键=值(键包含值)

Swift 4.1可编码采用数组到键=值(键包含值),swift,swift4,Swift,Swift4,如何使用Swift可编码协议将存储在Swift中的数据解码/编码为(JSON或其他类型的数据表示;不重要)key=value结构,如以下所示: 正如您所看到的,它是一个timestamp=valuenotation结构(我对时间戳的格式没有任何问题,这是正常的) (我知道之前已经回答过关于键中存储的数据的问题,但是我的问题不同,因为它特定于在平面键=值结构中仅转码了2个值的对象数组) 这是我的代码,它处理两个对象: MetricResult=包含时间戳和测量值 MetricResults=包含

如何使用Swift可编码协议将存储在Swift中的数据解码/编码为(JSON或其他类型的数据表示;不重要)key=value结构,如以下所示:

正如您所看到的,它是一个
timestamp=value
notation结构(我对时间戳的格式没有任何问题,这是正常的)

(我知道之前已经回答过关于键中存储的数据的问题,但是我的问题不同,因为它特定于在平面键=值结构中仅转码了2个值的对象数组)

这是我的代码,它处理两个对象:

MetricResult
=包含时间戳和测量值

MetricResults
=包含应正确编码的MetricResult数组

我已经设法为
MetricResult
编码了,但在阅读时,我不知道如何处理实际包含数据的变量键

struct MetricResult : Codable {
    var date   = Date()
    var result = Int(0)

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: Date.self)
        try container.encode(result, forKey: date)
    }

    init(from decoder: Decoder) throws {
        //how do deal with variable key name here??
    }
}

struct MetricResults: Codable {

    var results = [MetricResult]()

    func encode(to encoder: Encoder) throws {
        //how do deal with variable key name here??
    }

    init(from decoder: Decoder) throws {
        //how do deal with variable key name here??
    }
}

extension Date: CodingKey {

    //MARK: - CodingKey compliance

    public init?(intValue: Int)       {
        return nil
    }

    public init?(stringValue: String) {
        self.init(stringFirebase: stringValue)
    }

    public var intValue: Int?{
        return nil
    }

    public var stringValue: String {
        return stringFirebase()
    }

}

你很接近;您已经解决了最棘手的部分,即如何将日期转换为编码键(请确保将此
标记为private
;系统的其他部分也可能希望以另一种方式将日期用作编码键)

主要问题是,在本规范中,MetricResult本身不能进行编码。你不能只编码“一个键值对”,它只能被编码为某个东西的一部分(例如字典)。所有编码/解码必须由MetricResults通过以下方式完成:

extension MetricResults: Codable {
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: Date.self)
        for result in results {
            try container.encode(result.result, forKey: result.date)
        }
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: Date.self)
        for date in container.allKeys {
            let result = try container.decode(Int.self, forKey: date)
            results.append(MetricResult(date: date, result: result))
        }
    }
}

真有魅力!我错过了所有钥匙的供应。谢谢你的回答,罗布。