Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing JSON using Decodable in Swift 4

Can Someone help me to solve the problem, length of Int I am trying to get values from a JSON. After executing, I always get the error is:

Error serializing json: dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "coord", intValue: nil), CodingKeys(stringValue: "lon", intValue: nil)], debugDescription: "Parsed JSON number <-77.20999999999999> does not fit in Int.", underlyingError: nil))

My JSON: I am trying to get the first node, which is "coord"

{
  "coord": {
    "lon": -77.21,
    "lat": 38.84
  },
  "weather": [
    {
      "id": 741,
      "main": "Fog",
      "description": "fog",
      "icon": "50n"
    },
    {
      "id": 701,
      "main": "Mist",
      "description": "mist",
      "icon": "50n"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 287.75,
    "pressure": 1014,
    "humidity": 77,
    "temp_min": 284.15,
    "temp_max": 292.15
  },
  "visibility": 16093,
  "wind": {
    "speed": 1.53,
    "deg": 282.001
  },
  "clouds": {
    "all": 1
  },
  "dt": 1526025120,
  "sys": {
    "type": 1,
    "id": 3131,
    "message": 0.0048,
    "country": "US",
    "sunrise": 1526032792,
    "sunset": 1526083866
  },
  "id": 420039291,
  "name": "Arlington",
  "cod": 200
}

Struct Class: this class will define structure of an object

import Foundation

struct TestingClass: Decodable{
    let coord: Coord
}

struct Coord: Decodable{
    let lon: Int?
    let lat: Int?
}

ViewController: This class will have a function to get JSON from internet

override func viewDidLoad() {
        super.viewDidLoad()
        initialization()
    }

    func initialization(){

        let jsonUrlString="http://api.openweathermap.org/data/2.5/weather?zip=22003,us&appid=c632597b1892b4d415c64ca0e9fca1f1"
        guard let url = URL(string: jsonUrlString) else { return }

        URLSession.shared.dataTask(with: url) { (data, response, err) in

            guard let data = data else { return }

            do {

                let courses = try JSONDecoder().decode(TestingClass.self, from: data)
                print(courses.coord.lat)

            } catch let jsonErr {
                print("Error serializing json:", jsonErr)
            }
        }.resume()

    }
like image 957
Benjamin So Avatar asked May 11 '18 10:05

Benjamin So


1 Answers

Please read the error message carefully. The error is very clear

Parsed JSON number <-77.20999999999999> does not fit in Int

Int represents integer values without fractional digits. There are only two numeric JSON types, Int and Double.

Coordinates are always Double

struct Coord: Decodable {
    let lon: Double
    let lat: Double
}

Note Don't declare lat and long as optional, if a coordinate exists it contains always both values.

like image 51
vadian Avatar answered Oct 03 '22 05:10

vadian