如何在模型属性含API经纬度计算城市名时完成属性填充?
天气APP获取城市名的问题与解决方法
我正在开发一款简易天气APP,需展示用户城市名(此部分遇到问题)、当前温度、每日最高/最低温、风速、湿度。OpenWeatherMap API提供了除城市名外的所有数据,我难以梳理获取城市名的逻辑流程。
失败尝试
- 创建包含天气报告所有属性的
WeatherReport模型,其中city为可选属性,需通过逆地理编码(经纬度转地名)计算得到。 - 通过
.task从API下载数据并解码到模型(此步骤正常工作)。 - 填充
city属性的两次失败尝试:- 尝试1:为
lat、lon添加didSet属性观察器调用reverseGeocode函数,但因多变量var声明不能有显式getter/setter失败。 - 尝试2:修改
reverseGeocode返回WeatherReport,但因未将其视为异步函数,导致时序问题,视图卡在加载状态。
- 尝试1:为
最终解决方案
将reverseGeocode改为异步函数,使用async await处理,解决了数据填充的时序问题,代码如下:
func getCurrentWeather(latitude: CLLocationDegrees, longitude: CLLocationDegrees) async throws -> WeatherReport? { do { guard let url = URL(string: "https://api.openweathermap.org/data/3.0/onecall?lat=\(latitude)&lon=\(longitude)&exclude=current,minutely,hourly, alerts&appid=19054ace743dfdfd9&units=imperial") else { throw NetworkError.badURL} let (data, response) = try await URLSession.shared.data(from: url) guard let response = response as? HTTPURLResponse else { throw NetworkError.badResponse } guard response.statusCode >= 200 && response.statusCode < 300 else { throw NetworkError.badStatus } let decodedData = try JSONDecoder().decode(WeatherReport.self, from: data) let decodedDataWithCity = try await decodedData.reverseGeocode() return decodedDataWithCity } catch NetworkError.badURL { print("Error creating URL") } catch NetworkError.badResponse { print("Didn't get a valid response") } catch NetworkError.badStatus { print("Didn't get a 2xx status code from response") } catch { print("An error occurred downloading the data") } return nil }
func reverseGeocode() async throws -> WeatherReport? { let geocoder = CLGeocoder() let location = CLLocation(latitude: lat, longitude: lon) var report: WeatherReport? do { let placemarks = try await geocoder.reverseGeocodeLocation(location) let placemark = placemarks.first report = WeatherReport(lat: lat, lon: lon, city: placemark?.locality, timezone: timezone, timezoneOffset: timezoneOffset, daily: daily) } catch { print("Error: \(error.localizedDescription)") } return report }
内容的提问来源于stack exchange,提问作者lolrie
相关产品推荐
相关产品推荐

