调用OpenWeatherMap API获取数据时URL强制解包崩溃问题排查
问题原因与修复方案
直接报错原因
你当前的闪退是URL(string: url)!强制解包nil触发的,具体有以下几个问题:
- URL字符串存在无效空格:你定义的url字符串
http:// api.openweathermap.org中,协议头后多了一个空格,导致URL(string: url)初始化失败返回nil,强制解包空值直接触发崩溃。 - 强制解包Optional不符合安全规范:即使修复空格问题,只要URL字符串存在格式错误,强制解包都会直接引发闪退,必须用可选绑定做校验。
其他隐含问题
- 解析结构体字段与接口返回不匹配:OpenWeatherMap接口返回的coord节点下,经纬度字段为
lat(纬度)、lon(经度),你定义的longitude、latitude和接口字段名不对应,请求成功后也会解析失败。 - HTTP请求被ATS拦截:iOS默认禁止明文HTTP请求,你使用的http开头的接口地址会被系统拦截,需要改为HTTPS协议,或者在Info.plist中配置ATS例外(不推荐)。
- 接口密钥需要替换:代码中的
myAppID需要替换为你在openweathermap平台申请的有效AppID,否则接口会返回401无权错误。
修复后代码
数据解析结构
struct CitiesWeather: Decodable { var coord : Coordinate? } struct Coordinate: Decodable { var lon: Double var lat: Double }
业务逻辑代码
class DayWeatherViewModel: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 移除空格、替换为HTTPS协议,注意替换myAppID为你的有效密钥 let url = "https://api.openweathermap.org/data/2.5/weather?q=London&appid=myAppID" getData(from: url) } func getData(from url: String) { // 可选绑定校验URL有效性,避免强制解包闪退 guard let validUrl = URL(string: url) else { print("URL格式非法") return } let task = URLSession.shared.dataTask(with: validUrl) { data, response, error in guard let data = data, error == nil else { print("请求出错:\(error?.localizedDescription ?? "未知错误")") return } do { let result = try JSONDecoder().decode(CitiesWeather.self, from: data) print(result.coord) print(result.coord?.lat) print(result.coord?.lon) } catch { print("解析失败:\(error.localizedDescription)") } } task.resume() } }
内容的提问来源于stack exchange,提问作者Mikl.hart
相关产品推荐
相关产品推荐

