运行时发出多个JSON CodingKeys值

时间:2018-06-24 15:42:33

标签: json swift

假设我们具有以下JSON结构:

    {
    "July": [
        {
        ...
            "startDate": "July 10",
            "endDate": "July 11",
        ...
        },
        {
            ...
        },
        {
            ...
        },
        {
            ...
        }
    ]
}

我试图仅使用本机swift使用以下结构解析此API。

struct Listing: Codable {
    let months: [Month]


    enum CodingKeys: String, CodingKey {
        case months = "June" //here we need all months for the whole year.
    }

}

struct Month: Codable {
    ...
    let startDate: String
    let endDate: String
    ...

    enum CodingKeys: String, CodingKey {
        ...
    }
}

问题是API每次在新的月份返回新的JSON响应时,都会按请求返回每个请求,因此我需要两个“ CodingKeys”用例:“ July”,“ August”等,同时使用Month结构是可重用的。 尽管我想可以有一个更优雅的解决方案,但是有一个想法可以解决映射实体的问题。如果您有任何简化解决方案的想法,请告诉我。

1 个答案:

答案 0 :(得分:1)

首先,如果仅打算解码JSON,则仅采用Decodable

我建议将months解码为字典[String:[Month]]

struct Listing: Decodable {
    let months: [String:[Month]]
}

然后仅通过已知的月份键获取Month数组。

或使用枚举

enum MonthName : String, Decodable  {
    private enum CodingKeys : String, CodingKey { case january = "January", february = "February", ... december = "December" }
    case January, February, ... December
}

struct Listing: Decodable {
    let months: [MonthName:[Month]]
}

编辑:

您还可以编写一个自定义的初始化程序来提取Month数组,它假定根对象中只有一个带有一对键值对的字典。

struct Listing: Decodable {

    let months: [Month]

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let monthData = try container.decode([String:[Month]].self)
        months = monthData[monthData.keys.first!]!
    }
}