JSON parsing in Swift 4 with complex & nested data

前端 未结 2 1460
深忆病人
深忆病人 2021-01-15 12:14

I am currently trying to make a weather app using JSON from https://openweathermap.org but I am having trouble with the weather part in the JSON file. I am not sure how to a

相关标签:
2条回答
  • 2021-01-15 12:46

    You need to properly identify your json string and provide all necessary structures to decode it. Just by looking at the json provided you can have an idea of the necessary structs to decode it properly:

    struct CurrentLocalWeather: Codable {
        let base: String
        let clouds: Clouds
        let cod: Int
        let coord: Coord
        let dt: Int
        let id: Int
        let main: Main
        let name: String
        let sys: Sys
        let visibility: Int
        let weather: [Weather]
        let wind: Wind
    }
    struct Clouds: Codable {
        let all: Int
    }
    struct Coord: Codable {
        let lat: Double
        let lon: Double
    }
    struct Main: Codable {
        let humidity: Int
        let pressure: Int
        let temp: Double
        let tempMax: Int
        let tempMin: Int
        private enum CodingKeys: String, CodingKey {
            case humidity, pressure, temp, tempMax = "temp_max", tempMin = "temp_min"
        }
    }
    struct Sys: Codable {
        let country: String
        let id: Int
        let message: Double
        let sunrise: UInt64
        let sunset: UInt64
        let type: Int
    }
    struct Weather: Codable {
        let description: String
        let icon: String
        let id: Int
        let main: String
    }
    struct Wind: Codable {
        let deg: Int
        let speed: Double
    }
    

    let weatherData = Data("""
    {"base"  : "stations",
     "clouds": { "all": 36 },
     "cod"   : 200,
     "coord" : { "lat": 51.51,
                 "lon": -0.13},
     "dt": 1507497600,
     "id": 2643743,
     "main": {
            "humidity": 82,
            "pressure": 1021,
            "temp": 10.65,
            "temp_max": 13,
            "temp_min": 9},
     "name": "London",
     "sys": {
            "country": "GB",
            "id": 5091,
            "message": 0.0036,
            "sunrise": 1507443264,
            "sunset": 1507483213,
            "type": 1 },
     "visibility": 10000,
     "weather": [{
        "description": "scattered clouds",
        "icon": "03n",
        "id": 802,
        "main": "Clouds"}],
     "wind": {
        "deg": 200,
        "speed": 1.5
        }
     }
    """.utf8)
    

    let decoder = JSONDecoder()
    
    do {
        let currentLocalWeather = try decoder.decode(CurrentLocalWeather.self, from: weatherData)
        print(currentLocalWeather)   // "CurrentLocalWeather(base: "stations", clouds: __lldb_expr_367.Clouds(all: 36), cod: 200, coord: __lldb_expr_367.Coord(lat: 51.509999999999998, lon: -0.13), dt: 1507497600, id: 2643743, main: __lldb_expr_367.Main(humidity: 82, pressure: 1021, temp: 10.65, temp_max: 13, temp_min: 9), name: "London", sys: __lldb_expr_367.Sys(country: "GB", id: 5091, message: 0.0035999999999999999, sunrise: 1507443264, sunset: 1507483213, type: 1), visibility: 10000, weather: [__lldb_expr_367.Weather(description: "scattered clouds", icon: "03n", id: 802, main: "Clouds")], wind: __lldb_expr_367.Wind(deg: 200, speed: 1.5))\n"
    } catch {
        print(error)
    }
    
    0 讨论(0)
  • 2021-01-15 13:03

    You need to define types for the custom types in your JSON, e.g. weather, clouds, coord, etc. I would recommend looking at the example in the documentation.

    In the example, the Landmark type has a 'location' property which is of Coordinate type. You could even use the Coordinate type in the example for the coord property in your JSON object. However, you will need to provide the correct keys using the CodingKey protocol which is also described in the documentation. For example, your Coordinate type may look like this:

    struct Coordinate: Codable {
        var latitude: Double
        var longitude: Double
    
        enum CodingKeys: String, CodingKey {
            case latitude = "lat"
            case longitude = "lon"
        }
    }
    
    0 讨论(0)
提交回复
热议问题