You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:49:22