Codable Error - Expected to decode Dictionary<String, Any> but found an array instead

巧了我就是萌 提交于 2019-12-06 07:59:24

The variable names in forecastDay do not differ from the keys in the JSON and init(from decoder:) does nothing custom either, so the struct for a forecast day period can be simplified.

struct ForecastDayPeriod: Decodable {
    let period: Int
    let icon: String
    let title: String
    let fcttext: String
}

Now it's best to use an enum with key(s) for each level in the JSON. Also, init(from decoder:) should not create a new JSONDecoder.

struct ForecastDay: Decodable {

    let periods: [ForecastDayPeriod]

    enum CodingKeys: String, CodingKey {
        case forecast
    }

    enum ForecastKeys: String, CodingKey {
        case txtForecast = "txt_forecast"
    }

    enum TxtForecastKeys: String, CodingKey {
        case forecastday
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let forecast = try values.nestedContainer(keyedBy: ForecastKeys.self,
                                                  forKey: .forecast)
        let txtForecast = try forecast.nestedContainer(keyedBy: TxtForecastKeys.self,
                                                       forKey: .txtForecast)

        periods = try txtForecast.decode([ForecastDayPeriod].self,
                                         forKey: .forecastday)        
    }

}

Now it should be possible to decode the JSON from the pastebin example.

do {
    let jsonData: Data = ...
    let forecastDay = try JSONDecoder().decode(ForecastDay.self, from: jsonData)
} catch {
    print("Error: \(error)")
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!