I am trying to parse some JSON in Swift that I was previously parsing in Objective-C and am having some difficulties.
In objective-C I was able to parse it simply enough using:
NSError* error;
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSNumber *temp = jsonResults[@"main"][@"temp"];
NSNumber *humidity = jsonResults[@"main"][@"humidity"];
In Swift, my code so far is giving errors when I try to serialize into a dictionary or, alternatively, if I serialize intoa string when I try to access the values in the JSON.
What is the proper way to do this in Swift. Here is version where I try to to serialize into Dictionary and it gives an error
//assemble url query items
components.queryItems = queryItems
let url = components.url
let task = URLSession.shared.dataTask(with: url!) { //open 2
[weak self] data, response, error in
print("heard back from task")
guard let data = data, error == nil else { return }
do {
let jsonResults = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [Dictionary:Any]
//Gives error Dictionary' requires that 'Value' conform to 'Hashable'
let main = jsonResults["main"] as Any
let temp = main[3]
completion("got here")
} catch let error as NSError {
print(error)
}
Here is a sample of the JSON:
{"coord":{"lon":10.73,"lat":59.91},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"base":"stations","main":{"temp":49.62,"feels_like":43.45,"temp_min":48,"temp_max":52,"pressure":987,"humidity":30},"wind":{"speed":1.99,"deg":95,"gust":7},"clouds":{"all":95},"dt":1589387530,"sys":{"type":3,"id":2009047,"country":"NO","sunrise":1589337830,"sunset":1589398989},"timezone":7200,"id":3143242,"name":"Oslo County","cod":200}
In swift you only need the below code: -
Model:
struct Model: Codable {
let coord: Coord
let weather: [Weather]
let base: String
let main: Main
let wind: Wind
let clouds: Clouds
let dt: Int
let sys: Sys
let timezone, id: Int
let name: String
let cod: Int
}
struct Clouds: Codable {
let all: Int
}
struct Coord: Codable {
let lon, lat: Double
}
struct Main: Codable {
let temp, feelsLike: Double
let tempMin, tempMax, pressure, humidity: Int
enum CodingKeys: String, CodingKey {
case temp
case feelsLike = "feels_like"
case tempMin = "temp_min"
case tempMax = "temp_max"
case pressure, humidity
}
}
struct Sys: Codable {
let type, id: Int
let country: String
let sunrise, sunset: Int
}
struct Weather: Codable {
let id: Int
let main, description, icon: String
}
struct Wind: Codable {
let speed: Double
let deg, gust: Int
}
Parsing:
do {
let model = try JSONDecoder().decode(Model.self, from: data)
} catch {
print(error.localizedDescription)
}