Swift 4.1 кодируемое принятие для массива к ключу = значению (ключ содержит значение) - PullRequest
0 голосов
/ 02 июня 2018

Как использовать протокол Swift Codable для декодирования / кодирования данных, хранящихся в Swift, в виде массива объектов (только с 2 значениями) в (JSON или другой тип представления данных; не имеет значения) ключ = значениеструктура, подобная этой:

enter image description here

Как вы можете видеть ее структуру записи timestamp = value (у меня нет проблем с форматированием временных отметок, это нормально)

(я знаю, что ранее задавались вопросы о данных, хранящихся в ключах, однако мои вопросы отличаются, поскольку они специфичны для массивов объектов, в которых только 2 значения транскодированы в структуре с плоским ключом = значением).

Вот мой код, он имеет дело с 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()
    }

}

1 Ответ

0 голосов
/ 02 июня 2018

Ты очень близко;вы уже разработали самую сложную часть, а именно, как превратить Date в CodingKey (обязательно отметьте это private; возможно, другие части системы также захотят использовать Date как CodingKey по-другому).

Основная проблема заключается в том, что в этой спецификации MetricResult сам по себе не может быть Codable.Вы не можете закодировать только «пару ключ-значение».Это может быть закодировано только как часть чего-то (например, словарь).Все кодирование / декодирование должно выполняться 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))
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...