Swift4解析嵌套JSON:无法获取weather数组main字段的解决方法
解决Swift中访问Weather API数组字段的问题
嘿,我仔细看了你的代码和API返回的JSON数据,一下子就找到问题啦!你之所以获取不到weather里的main字段,核心原因是对weather字段的类型判断错了。
先看API返回的关键部分:
{ "coord": { "lon": 139, "lat": 35 }, "weather": [ { "id": 520, "main": "Rain", "description": "light intensity shower rain", "icon": "09d" } ], // ... 其他字段 }
这里的weather是一个数组(用[]包裹),里面包含一个字典元素。但你的代码里把它当成了单个字典来转换:
if let weather = dict["weather"] as? Dictionary<String,AnyObject>
这一步转换必然失败,所以后面的代码根本不会执行,自然拿不到main字段的值。
接下来给你修正方案,还有几个小细节优化:
1. 修正weather字段的类型转换
把weather的类型改成数组,也就是[[String: Any]](Swift 3+推荐用Any代替AnyObject,更灵活),然后取数组的第一个元素:
if let weatherArray = dict["weather"] as? [[String: Any]], let firstWeather = weatherArray.first, let main = firstWeather["main"] as? String { self._weatherType = main }
这里用了链式可选绑定,既安全又简洁,避免了多层嵌套。
2. 温度转换的小坑
你的温度转换代码里,9/5是整数除法,在Swift里会得到1而不是1.8,导致转换结果错误。要改成浮点数除法:
let kelvinToFarenheitPre = (currentTemp * (9.0/5) - 459.67)
或者用Double(9)/5,确保运算结果是浮点数。
完整修正后的代码
if let dict = result.value as? [String: Any] { // 获取城市名称 if let name = dict["name"] as? String { self._cityName = name } // 获取天气类型(修正后的部分) if let weatherArray = dict["weather"] as? [[String: Any]], let firstWeather = weatherArray.first, let main = firstWeather["main"] as? String { self._weatherType = main } // 获取温度并转换 if let mainDict = dict["main"] as? [String: Any], let currentTemp = mainDict["temp"] as? Double { let kelvinToFarenheitPre = (currentTemp * (9.0/5) - 459.67) let kelvinToFarenheit = Double(round(10 * kelvinToFarenheitPre)/10) self._currentTemp = kelvinToFarenheit } print(self.weatherType) print(self.cityName) }
额外建议
如果你的Swift版本比较新(Swift 5+),可以考虑用Codable协议来解析JSON,这样类型更安全,代码也更整洁,不用手动做大量的类型转换。比如定义对应的Model结构体:
struct WeatherResponse: Codable { let name: String let weather: [Weather] let main: Main struct Weather: Codable { let main: String } struct Main: Codable { let temp: Double } }
然后解析的时候直接用JSONDecoder:
do { let response = try JSONDecoder().decode(WeatherResponse.self, from: jsonData) self._cityName = response.name self._weatherType = response.weather.first?.main ?? "Unknown" let currentTemp = response.main.temp // 温度转换逻辑... } catch { print("解析错误:\(error)") }
这样能避免很多手动类型转换的错误,推荐尝试哦!
内容的提问来源于stack exchange,提问作者MD Sazid Hasan Dip
相关产品推荐
相关产品推荐

