ios - 如何配置 SwiftUI openweathermap 应用程序以搜索包含多个单词的城市名称(例如纽约市)
问题描述
我正在构建一个使用 openweathermap API 的 SwiftUI 天气应用程序。我的应用程序当前配置为识别单字城市名称。但是,我还想配置应用程序以识别具有多个单词的城市名称(例如纽约市、洛杉矶......)。我不知道从哪里开始。是否有用于配置 API 密钥 URL 的协议来处理此问题?
https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&units=imperial&appid=<myAPIKey>
还是需要在我的视图模型的其他地方以编程方式处理?
到目前为止,这是我的应用程序的代码,作为参考:
内容视图
import SwiftUI
struct ContentView: View {
// Whenever something in the viewmodel changes, the content view will know to update the UI related elements
@StateObject var viewModel = WeatherViewModel()
@State private var cityName = ""
var body: some View {
NavigationView {
VStack {
TextField("Enter City Name", text: $cityName).textFieldStyle(.roundedBorder)
Button(action: {
viewModel.fetchWeather(for: cityName)
cityName = ""
}, label: {
Text("Search")
.padding(10)
.background(Color.green)
.foregroundColor(Color.white)
.cornerRadius(10)
})
List {
ForEach(viewModel.cityNameList) { city in
NavigationLink(destination: DetailView(detail: city)) {
HStack {
Text(city.name).font(.system(size: 32))
}
}
}
}
Spacer()
}.navigationTitle("Weather MVVM")
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
视图模型
import Foundation
class WeatherViewModel: ObservableObject {
@Published var cityNameList = [WeatherModel]()
func fetchWeather(for cityName: String) {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&units=imperial&appid=<MyAPIKey>") else { return }
let task = URLSession.shared.dataTask(with: url) { data, _, error in
guard let data = data, error == nil else { return }
do {
let model = try JSONDecoder().decode(WeatherModel.self, from: data)
DispatchQueue.main.async {
self.cityNameList.append(model)
}
}
catch {
print(error) // <-- you HAVE TO deal with errors here
}
}
task.resume()
}
}
模型
import Foundation
struct WeatherModel: Identifiable, Codable {
let id = UUID()
var name: String = ""
var main: CurrentWeather = CurrentWeather()
var weather: [WeatherInfo] = []
func firstWeatherInfo() -> String {
return weather.count > 0 ? weather[0].description : ""
}
}
struct CurrentWeather: Codable {
var temp: Float = 0.0
}
struct WeatherInfo: Codable {
var description: String = ""
}
详细视图
import SwiftUI
struct DetailView: View {
var detail: WeatherModel
var body: some View {
VStack(spacing: 20) {
Text(detail.name)
.font(.system(size: 32))
Text("\(detail.main.temp)")
.font(.system(size: 44))
Text(detail.firstWeatherInfo())
.font(.system(size: 24))
}
}
}
struct DetailView_Previews: PreviewProvider {
static var previews: some View {
DetailView(detail: WeatherModel.init())
}
}
解决方案
推荐阅读
- python - Dialogflow:AttributeError:“MapComposite”对象没有属性“DESCRIPTOR”
- micropython - 如何在 Arduino Nano Connect RP2040 上使用 MicroPython 发出 HTTP 请求
- facebook - Facebook 登录已禁用
- kubernetes - 使用内部负载平衡器配置时无法访问 GKE 上的应用程序
- c# - 如何使用 Photon 准确同步触发动画?
- python - if语句比较jinja2模板中的字符串
- python - 如何将动态数组转换为 Cython 中的列表?
- python - Google Cloud Functions 自定义日志标签
- python - 如何在图上设置强化学习问题?
- ios - 使用 .framework 依赖做出本机反应的示例插件