I am attempting to set up a new SwiftUI weather app that uses the OpenWeatherMap Api string "api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}" to pass in a city. I set up my contentView, model, and viewModel to return the city name, temp, and weather description, but am still getting the following error when I run the app:
2021-11-09 23:26:56.923188-0500 SwftUIMVVMWeatherDemo[13982:634181] [boringssl] boringssl_metrics_log_metric_block_invoke(144) Failed to log metrics
failed
My contentView, model, and viewModel are as follows:
ContentView
import SwiftUI
struct ContentView: View {
@StateObject var viewModel = WeatherViewModel()
var body: some View {
NavigationView {
VStack {
Text(viewModel.name)
.font(.system(size: 32))
Text(viewModel.temp)
.font(.system(size: 44))
Text(viewModel.descriptionText)
.font(.system(size: 24))
Spacer()
}
.navigationTitle("Weather MVVM")
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Model
import Foundation
struct WeatherModel: Codable {
let name: String
let main: CurrentWeather
}
struct CurrentWeather: Codable {
let temp: Float
let weather: [WeatherInfo]
}
struct WeatherInfo: Codable {
let description: String
}
ViewModel
import Foundation
class WeatherViewModel: ObservableObject {
@Published var name: String = "-"
@Published var temp: String = "-"
@Published var descriptionText: String = "-"
init() {
fetchWeather()
}
func fetchWeather() {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=chicago&appid=<myAPIKeyGoesHere>") else {
return
}
let task = URLSession.shared.dataTask(with: url) { data, _, error in
// get data
guard let data = data, error == nil else {
return
}
//convert data to model
do {
let model = try JSONDecoder().decode(WeatherModel.self, from: data)
DispatchQueue.main.async {
self.name = model.name
self.temp = "\(model.main.temp)"
self.descriptionText = model.main.weather.first?.description ?? "No Description"
}
}
catch {
print("failed")
}
}
task.resume()
}
}
The error message is vague. Any idea what might be wrong? Thanks for the feedback!
CodePudding user response:
it maybe due to your incorrect model. Try this:
struct WeatherModel: Codable {
let name: String
let main: CurrentWeather
let weather: [WeatherInfo] // <--- here
}
struct CurrentWeather: Codable {
let temp: Float
// let weather: [WeatherInfo] // <--- NOT here
}
Also the city is Chicago
, although it seems to work with chicago