Ali Ahmed
Ali Ahmed

Reputation: 51

The data couldn’t be read because it isn’t in the correct format with openweathermap api

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

Answers (1)

Miguel Tepale
Miguel Tepale

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

Related Questions