Flutter调用WeatherAPI获取天气数据报错问题求助
解决Flutter调用WeatherAPI抛出“Failed to load weather data”异常的问题
问题根源
JSON解析路径错误
WeatherAPI返回的JSON是嵌套结构,temp_c在current节点下,name(城市名)在location节点下,condition.text在current.condition节点下,你的代码直接读取顶层键会导致解析失败。冗余的位置请求
无论current参数是否为true,代码都会先执行getCurrentPosition(),如果不需要获取当前位置(current=false),这一步会触发不必要的权限申请或位置服务错误,直接进入catch块抛出异常。异常信息丢失
catch块直接抛出固定的Exception('Failed to load weather data'),掩盖了实际错误(比如API密钥无效、网络错误、权限不足等),无法定位具体问题。语法错误
desc = json['condition:text'];是错误的键名写法,正确的嵌套路径应该是json['current']['condition']['text']。
修复后的代码
1. 修正API调用逻辑
class CallToApi { Future<WeatherModel> callWeatherApi(bool current, String cityName) async { try { // 仅当需要当前位置时,才获取位置信息 if (current) { Position currentPosition = await getCurrentPosition(); List<Placemark> placemarks = await placemarkFromCoordinates( currentPosition.latitude, currentPosition.longitude); Placemark place = placemarks[0]; cityName = place.locality!; } var url = Uri.https('api.weatherapi.com', '/v1/current.json', {"key": apiKey, 'q': cityName}); final http.Response response = await http.get(url); log(response.body.toString()); if (response.statusCode == 200) { final Map<String, dynamic> decodedJson = json.decode(response.body); return WeatherModel.fromMap(decodedJson); } else { // 抛出API返回的错误信息,方便排查 throw Exception('API返回错误: ${response.body}'); } } catch (e) { // 打印实际错误,再抛出 log('实际错误: $e'); throw Exception('加载天气数据失败: $e'); } } }
2. 修正WeatherModel解析逻辑
class WeatherModel { final String temp; final String city; final String desc; WeatherModel.fromMap(Map<String, dynamic> json) : temp = json['current']['temp_c'].toString(), city = json['location']['name'], desc = json['current']['condition']['text']; }
额外排查步骤
- 确认
apiKey是有效的WeatherAPI密钥,没有拼写错误 - 检查设备网络连接正常
- 如果需要获取当前位置,确保已在
AndroidManifest.xml(Android)或Info.plist(iOS)中添加位置权限申请 - 查看VSCode控制台的
log输出,里面会打印实际错误信息和API返回的原始JSON,帮助进一步定位问题
内容的提问来源于stack exchange,提问作者Dedy Simamora
相关产品推荐
相关产品推荐

