我正在尝试从“列表”部分下面的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以获取所需的值感到困惑。这是我的可编码课程
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))
我相信我将Codable类的结构错误,但似乎无法弄清楚原因。
main
中键list
的值是一个数组。将结构更改为
struct RootList : Decodable {
let list : [List]
}
struct List : Decodable {
let main : Main
let weather : [Weather]
let dateText : String
enum CodingKeys: String, CodingKey { case main, dateText = "dtTxt", weather }
}
struct Weather : Decodable {
let icon : String
let description: String
}
struct Main : Decodable {
let temp : Double
}
键真的是dt_txt
吗?我得到dtTxt