Swift调用OpenWeather API获取温湿度数据返回nil如何解决?
问题排查与修复方案
核心错误点
- API返回结构理解错误:OpenWeather
/data/2.5/weather接口的返回数据中,temp、humidity属于根节点下的main字段,城市名称name属于根节点字段,你遍历的weather数组仅存储天气类型、图标等描述信息,不存在temp、humidity、name字段,强行从该数组取值自然全为nil。 - 多余的重复解析逻辑:你已经用
JSONDecoder解码了完整的返回数据,不需要再手动遍历weather数组重新赋值,额外的赋值操作反而把正确解析出来的数值覆盖成了nil。 - 不必要的请求头配置:OpenWeather的公开接口不需要配置
Authorization请求头,你已经在URL参数中携带了appid,额外加的Bearer头可能导致接口鉴权异常。 - Codable结构体定义偏差:
name字段不在main节点下,你当前的结构体定义无法正确解析到城市名称。 - 强制解包风险:代码中多处使用
!强制解包可选值,一旦接口返回异常会直接触发崩溃。
修复后代码
第一步:修正Codable结构体定义
// 对应接口返回根节点 struct WeatherResponse: Codable { let main: Weather let name: String? } // 对应main节点的温湿度数据 struct Weather: Codable { var temp: Double? var humidity: Int? }
第二步:重写fetchWeather方法
func fetchWeather(lat: Double, lon: Double, completionHandler: @escaping (Weather?, String?, Error?) -> Void) { let apikey = "替换为你的真实OpenWeather APIKey" // URL添加units=metric参数可直接返回摄氏度单位的温度,默认返回开尔文温度 guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=\(lat)&lon=\(lon)&appid=\(apikey)&units=metric") else { completionHandler(nil, nil, NSError(domain: "InvalidURL", code: -1)) return } // 不需要额外配置请求头 URLSession.shared.dataTask(with: url) { data, _, error in if let error = error { completionHandler(nil, nil, error) return } guard let data = data else { completionHandler(nil, nil, NSError(domain: "EmptyData", code: -2)) return } do { let response = try JSONDecoder().decode(WeatherResponse.self, from: data) completionHandler(response.main, response.name, nil) } catch { print("数据解析错误: \(error)") completionHandler(nil, nil, error) } }.resume() }
第三步:调整调用逻辑
func retrieve() { fetchWeather(lat: latitudeValue, lon: longitudeValue) { weather, cityName, error in if let error = error { print("请求失败: \(error.localizedDescription)") return } guard let weather = weather else { return } print("温度: \(weather.temp ?? 0),湿度: \(weather.humidity ?? 0),城市: \(cityName ?? "")") // UI更新必须切到主线程执行 DispatchQueue.main.async { self.humidityLabel.text = "湿度:\(weather.humidity ?? 0)%" } } }
内容的提问来源于stack exchange,提问作者user14908036
相关产品推荐
相关产品推荐

