Reputation: 51
I am developing weather app in swift with openweathermap api and parse json data with mvvm pattern.I have used this code it is displaying data could not be read because it's not in the correct format.
import UIKit
struct WeatherModel: Codable {
var main:String!
var description:String!
var icon:String!
var temp:Int?
enum CodingKeys: String, CodingKey {
case main = "main"
case description = "description"
case icon = "icon"
case temp = "temp"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
main = try values.decodeIfPresent(String.self, forKey: .main)
description = try values.decodeIfPresent(String.self, forKey: .description)
icon = try values.decodeIfPresent(String.self, forKey: .icon)
temp = try values.decodeIfPresent(Int.self, forKey: .temp)
}
}
This is model
import UIKit
import Alamofire
class WeatherViewModel{
var modelWeather = [WeatherModel]()
weak var vc: ViewController?
func getWeather() {
AF.request("http://api.openweathermap.org/data/2.5/weather?q="+(vc?.cityTextField.text)!+"&units=metric&appid=88236c7916643a06e2cd64d56f4e5077", method: .get).response{
response in
debugPrint(response)
if let data = response.data
{
do{
let apiResponse = try JSONDecoder().decode(WeatherModel.self, from: data)
self.modelWeather.append(apiResponse)
debugPrint(apiResponse)
DispatchQueue.main.async {
self.vc?.reloadInputViews()
}
}catch let error{
print(error.localizedDescription)
}
}
}
}
}
{"coord":{"lon":67.0822,"lat":24.9056},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":28,"feels_like":27.67,"temp_min":28,"temp_max":28,"pressure":1014,"humidity":44},"visibility":6000,"wind":{"speed":2.57,"deg":50},"clouds":{"all":0},"dt":1616474499,"sys":{"type":1,"id":7576,"country":"PK","sunrise":1616463159,"sunset":1616507028},"timezone":18000,"id":1174872,"name":"Karachi","cod":200}
This is response but error in apiresponse veriable.
Upvotes: 1
Views: 175
Reputation: 355
A good first step is to properly model Main
. I checked out the dummy data that was used in the comments and your main
property is missing the nested dictionaries inside the main
dictionary. You can map this by simply creating a struct that maps each dictionary key/value pair.
struct Main: Codable {
let temp: Double
let feels_like: Double
let temp_min: Double
// Continue to add the rest of the dictionaries here.
}
Once this is done, add this struct to your property and make it of type Main
, like so:
var main: Main
Also you don't need to add CodingKeys
unless your properties are going to be named differently than the property names that are coming back from the sever.
EDIT
If you wanna retrieve
var description:String!
var icon:String!
You'll need to make a Weather
struct as well.
Hopefully this helps and you can figure out the rest of the mapping for your WeatherModel
object.
Upvotes: 1