如何在Swift中解码JSON?

t5zmwmid  于 2022-11-21  发布在  Swift
关注(0)|答案(2)|浏览(164)

我有一个API JSON响应,如下所示。我想解码JSON以获得字典[String:Double]的数组,如[{"2020-01-01" : 0.891186}, {"2020-01-02" : 0.891186}]

{
    "rates": {
        "2020-01-01": {
            "EUR": 0.891186
        },
        "2020-01-02": {
            "EUR": 0.891186
        },
        "2020-01-03": {
            "EUR": 0.895175
        },
        "2020-01-04": {
            "EUR": 0.895175
        }
    }
}

我写了如下解码代码:

do {
            let data = try Data(contentsOf: appURL)
            let decoder = JSONDecoder()
            let response = try decoder.decode(Rates.self, from: data)
            response.rates
        } catch let jsonError {
            print(jsonError)
        }

我试着定义一个结构体:

struct Rates: Codable, Hashable {
    let rates: Point
}

struct Point {

}

但是我不知道应该在struct Point中写什么,因为日期不是一个一致的字段。

hi3rlvi2

hi3rlvi21#

下面是两种可能的解决方案,一种使用结构Point,另一种使用字典
第一个解是Point

struct Point: Codable {
    let date: String
    let rate: Double
}

然后创建一个自定义的init(from:),我们首先将json解码为一个字典[String: [String: Double]],然后将该字典Map到Point数组中。

struct Rates: Codable {
    let rates: [Point]

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let dictionary = try container.decode([String: [String: Double]].self, forKey: .rates)
        rates = dictionary.map { Point(date: $0.key, rate: $0.value.first?.value ?? .zero) }
    }
}

这是第二个解决方案,使用字典

struct Rates: Codable {
    let rates: [String: Double]

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let dictionary = try container.decode([String: [String: Double]].self, forKey: .rates)
        rates = dictionary.compactMapValues { $0.first?.value }
    }
}
z4bn682m

z4bn682m2#

struct Rates: Codable {
    let rates: [String: Point]
}

// MARK: - Point
struct Point: Codable {
    let eur: Double

    enum CodingKeys: String, CodingKey {
        case eur = "EUR"
    }
}

你可以这样做

相关问题