当我只想获取字典中的特定值时,如何解码字典值的 JSON 数组?
Posted
技术标签:
【中文标题】当我只想获取字典中的特定值时,如何解码字典值的 JSON 数组?【英文标题】:How do I decode JSON array of dictionary values in when I only want to grab specific values in the dictionary? 【发布时间】:2020-01-26 03:52:30 【问题描述】:我正在尝试从下面“列表”部分的 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))
我相信我的 Codable 课程结构错误,但似乎无法弄清楚原因。
【问题讨论】:
发布完整的 json 响应 【参考方案1】:list
中键 main
的值是一个数组。将结构更改为
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
【讨论】:
嘿 Vadian,谢谢你的回答。我将如何访问不同结构中的值?我无法使用打印在 do-catch 块中的forecast
对象访问它们。此外,如果我调用 let forecast = try JSONDecoder().decode(FiveDayWeatherInformation.Main.self, from:data)
,我会收到“没有与键关联的值”错误。
您必须始终解码根对象 (FiveDayWeatherInformation.RootList.self
)。然后你用forecast.main.temp
得到温度。使用代码完成,编译器会显示哪些属性可用。以上是关于当我只想获取字典中的特定值时,如何解码字典值的 JSON 数组?的主要内容,如果未能解决你的问题,请参考以下文章