Я пытаюсь получить конкретную c информацию из JSON ниже в разделе "список".
Образец JSON
{
city = {
coord = {
lat = "37.323";
lon = "-122.0322";
};
country = US;
id = 5341145;
name = Cupertino;
population = 58302;
sunrise = 1579965395;
sunset = 1580001833;
timezone = "-28800";
};
cnt = 40;
cod = 200;
list = (
{
clouds = {
all = 99;
};
dt = 1580018400;
"dt_txt" = "2020-01-26 06:00:00";
main = {
"feels_like" = "286.89";
"grnd_level" = 1011;
humidity = 78;
pressure = 1020;
"sea_level" = 1020;
temp = "287.29";
"temp_kf" = "-0.68";
"temp_max" = "287.97";
"temp_min" = "287.29";
};
sys = {
pod = n;
};
weather = (
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
);
wind = {
deg = 183;
speed = "0.77";
};
},
{
clouds = {
all = 88;
};
dt = 1580029200;
"dt_txt" = "2020-01-26 09:00:00";
main = {
"feels_like" = "286.55";
"grnd_level" = 1011;
humidity = 91;
pressure = 1020;
"sea_level" = 1020;
temp = "286.64";
"temp_kf" = "-0.51";
"temp_max" = "287.15";
"temp_min" = "286.64";
};
rain = {
3h = "1.88";
};
sys = {
pod = n;
};
weather = (
{
description = "light rain";
icon = 10n;
id = 500;
main = Rain;
}
);
wind = {
deg = 140;
speed = "1.04";
};
},
Однако я запутался о том, как структурировать мои объекты и декодировать JSON, чтобы получить нужные мне значения. Вот мой класс Codable
class FiveDayWeatherInformation: Codable {
struct Weather: Codable {
var description: String
var icon: String
enum CodingKeys: String, CodingKey {
case description
case icon
}
}
struct Main: Codable {
var temp: Double
enum CodingKeys: String, CodingKey {
case temp
}
}
struct ThreeHourItem: Codable {
var dateText: String
var weather: Weather
var main: Main
enum CodingKeys: String, CodingKey {
case main
case dateText = "dt_txt"
case weather
}
}
struct RootList: Codable {
let list: [[String:ThreeHourItem]]
enum CodingKeys: String, CodingKey {
case list
}
}
var rootList: RootList
enum CodingKeys: String, CodingKey {
case rootList = "list"
}
required public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.rootList = try values.decode(RootList.self, forKey: .rootList)
}
}
И именно здесь я пытаюсь получить значения
func fetchFiveDayForecastForCoordinates(latitude: CLLocationDegrees, longitude: CLLocationDegrees, completion: @escaping (_ weatherForecasts:[FiveDayWeatherInformation]?, Error?) -> Void) {
// to do
let url = URL(string: "http://api.openweathermap.org/data/2.5/forecast?lat=\(latitude)&lon=\(longitude)&APPID=APPID")
let urlRequest = URLRequest(url: url!)
let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
guard let data = data, error == nil else {
completion(nil, APIError.apiServiceError)
return
}
do {
let forecast = try JSONDecoder().decode(FiveDayWeatherInformation.RootList.self, from:data)
print(forecast)
} catch {
print(error)
}
}
task.resume()
}
Однако я продолжаю получать это предупреждение.
keyNotFound(CodingKeys(stringValue: "main", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "list", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), _JSONKey(stringValue: "clouds", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"main\", intValue: nil) (\"main\").", underlyingError: nil))
I Полагаю, я неправильно структурировал свой класс Codable, но не могу понять, почему.