如何解析包含动态城市名参数的天气API JSON数据?
问题:适配动态城市名的天气JSON数据解析
我是JSON解析新手,正在通过API获取天气数据。用户在文本框输入城市名,该名称会传入网络请求方法以获取对应城市的气温。返回的JSON数据结构如下:
{ "remainingCost": 0, "queryCost": 1, "messages": null, "locations": { "London": { "stationContributions": null, "values": [ { "wdir": 322.4, "uvindex": 3.0, "datetimeStr": "2022-09-28T17:00:00+01:00", "preciptype": "", "cin": -2.0, "cloudcover": 57.4, "pop": 19.0, "datetime": 1664384400000, "precip": 0.0, "solarradiation": 280.0, "dew": 4.0, "humidity": 49.9, "temp": 14.3, "visibility": 15.0, "wspd": 6.0, "severerisk": 10.0, "solarenergy": 1.0, "heatindex": null, "snowdepth": 0.0, "sealevelpressure": 1000.0, "snow": 0.0, "wgust": 15.4, "conditions": "Partially cloudy", "windchill": null, "cape": 11.0 } ] } } }
我已创建如下Decodable结构体来解析数据,当前能成功获取London的气温:
struct WeatherModel: Decodable { let locations: Locations } struct Locations: Decodable { let London: London } struct London: Decodable { let values: [Values] } struct Values: Decodable { let temp: Double }
但问题在于,locations下的键是用户输入的城市名,若输入Paris等其他城市,固定的结构体将无法适配。请问如何解决该问题以支持不同城市的天气数据解析?是否需要调整数据结构或更换API?
解决方案
不需要更换API,也不用大幅调整数据结构,只需要修改结构体定义,用字典类型处理动态城市名键即可。
具体修改代码
将原有的固定城市名结构体替换为字典映射,重命名相关结构体增强通用性:
struct WeatherModel: Decodable { let locations: [String: CityWeather] } struct CityWeather: Decodable { let values: [WeatherValue] } struct WeatherValue: Decodable { let temp: Double }
解析后获取气温
假设用户输入的城市名存在cityName变量中,解析完成后通过字典键直接取值:
// 假设已完成JSON解析得到weatherModel实例 if let cityWeather = weatherModel.locations[cityName], let firstWeatherValue = cityWeather.values.first { let temperature = firstWeatherValue.temp print("\(cityName)当前气温:\(temperature)℃") } else { print("未查询到该城市的天气数据") }
原理说明
Swift的Decodable协议原生支持字典类型的解析,会自动把locations下的动态键值对转换成[String: CityWeather]字典,不管用户输入什么城市名,都能正确匹配解析。这种写法还能兼容API返回多个城市数据的场景,灵活性更高。
内容的提问来源于stack exchange,提问作者Jake Jake
相关产品推荐
相关产品推荐

