Имена переменных в forecastDay
не отличаются от ключей в JSON, а init(from decoder:)
тоже ничего не меняет, поэтому структуру для прогнозируемого периода дня можно упростить.
struct ForecastDayPeriod: Decodable {
let period: Int
let icon: String
let title: String
let fcttext: String
}
ТеперьЛучше всего использовать перечисление с ключом (ами) для каждого уровня в JSON.Кроме того, init(from decoder:)
не должен создавать новый 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)
}
}
Теперь должна быть возможность декодировать JSON из примера pastebin.
do {
let jsonData: Data = ...
let forecastDay = try JSONDecoder().decode(ForecastDay.self, from: jsonData)
} catch {
print("Error: \(error)")
}