Проблема с JSON Decodable - PullRequest
       9

Проблема с JSON Decodable

0 голосов
/ 07 сентября 2018

Итак, я пытаюсь использовать JSON Decodable на игровой площадке для получения данных из конечной точки API. Я следовал за шагами, чтобы создать структуру и привести ее в соответствие с Decodable, вот так.

import Foundation


struct Weather: Decodable {
    let latitude: String
    let longitude: String
    let timezone: String
    let offset: Int
    let currently : Currently

    init(latitude: String,longitude: String,timezone: String,offset: Int,currently : Currently) {
        self.latitude = latitude
        self.longitude = longitude
        self.timezone = timezone
        self.offset = offset
        self.currently = currently
    }

    enum CodingKeys: String, CodingKey {
        case currently = "currently",latitude = "latitude",longitude = "longitude",timezone = "timezone", offset = "offset"
    }

    }



struct Currently: Decodable {
    let time: Int
    let summary: String
    let icon: String
    let precipIntensity: Double
    let precipProbability: Int
    let precipType: String
    let temperature: Double
    let apparentTemperature: Double
    let dewPoint: Double
    let humidity: Double
    let pressure: Double
    let windSpeed: Double
    let windGust: Double
    let windBearing: Double
    let cloudCover: Double
    let uvIndex: Double
    let visibility: Double


    init(time: Int,summary: String,icon: String,precipIntensity: Double,precipProbability: Int, precipType: String,temperature: Double,apparentTemperature: Double,dewPoint: Double, humidity: Double,pressure: Double,windSpeed: Double, windGust: Double,windBearing: Double,cloudCover: Double,uvIndex: Double,visibility: Double) {
        self.time = time
        self.summary = summary
        self.icon = icon
        self.precipIntensity = precipIntensity
        self.precipProbability = precipProbability
        self.precipType = precipType
        self.temperature = temperature
        self.apparentTemperature = apparentTemperature
        self.dewPoint = dewPoint
        self.humidity = humidity
        self.pressure = pressure
        self.windSpeed = windSpeed
        self.windGust = windGust
        self.windBearing = windBearing
        self.cloudCover = cloudCover
        self.uvIndex = uvIndex
        self.visibility = visibility

    }

    enum CodingKeys : Any, CodingKey {
        case time,summary,icon,precipIntensity,precipProbability,precipType,temperature,apparentTemperature,
        dewPoint,humidity,pressure,windSpeed,windGust,windBearing,cloudCover,uvIndex,visibility
    }

}

Но когда я пытаюсь выполнить URLSession и получить данные, я получаю эту ошибку

keyNotFound (CodingKeys (stringValue: «в настоящее время», intValue: nil)

Я не совсем уверен, что я сделал неправильно. Я смоделировал свой объект так же, как выглядит ответ json при вводе ссылки в браузер.

{  
   "latitude":42.3601,
   "longitude":-71.0589,
   "timezone":"America/New_York",
   "currently":{  
      "time":255657600,
      "summary":"Heavy Snow and Dangerously Windy",
      "icon":"snow",
      "precipIntensity":0.1692,
      "precipProbability":1,
      "precipType":"snow",
      "temperature":30.38,
      "apparentTemperature":13.49,
      "dewPoint":29.24,
      "humidity":0.95,
      "pressure":1006.67,
      "windSpeed":40.36,
      "windGust":83.48,
      "windBearing":63,
      "cloudCover":1,
      "uvIndex":0,
      "visibility":0.2
   },
   "offset":-5
}

Я включил структуру JSON для лучшего разъяснения направления, в котором я шел. Кто-нибудь может увидеть, где я ошибся?

Код для получения данных API также ниже

@objc func fetchWeatherData(location: String, time: Date){
    LocationService.getEventLocation(address: location) { (place) in
        guard let places = place else  {
            return
        }

        for place in places {
            print(place.coordinates?.latitude as Any)
            print(place.coordinates?.longitude as Any)
            let jsonURLString = "https://api.darksky.net/forecast/d455ebdd2abdcb5160adc4e70919367c/\(place.coordinates?.latitude ?? 0),\(place.coordinates?.longitude ?? 0),\(time.timeIntervalSince1970)?exclude=minutely,flags,hourly,daily,alerts"
            print(jsonURLString)
            guard let url = URL(string: jsonURLString) else {
                return
            }
            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, err) in
                guard let data = data else {
                    return
                }
                do {
                    let weather = try JSONDecoder().decode(Weather.self, from: data)
                    print(weather)
                } catch let jsonErr {
                    print("Error serializing json:", jsonErr)

                }

            }).resume()

        }
    }
}

1 Ответ

0 голосов
/ 07 сентября 2018

На самом деле вы должны получить

Предполагается декодировать строку, но вместо этого найдено число. codingPath: [CodingKeys (stringValue: "широта", intValue: ноль)]

потому что latitude и longitude равны Double (без двойных кавычек).

Кстати, вашим структурам не нужны ни инициализаторы, ни CodingKeys, этого достаточно:

struct Weather: Decodable {
    let latitude, longitude: Double  // must be Double not String
    let timezone: String
    let offset: Int
    let currently : Currently
}

struct Currently : Decodable {
    let time: Int
    let summary, icon: String
    let precipIntensity: Double
    let precipProbability: Double // must be Double not Int
    let precipType: String
    let temperature, apparentTemperature: Double
    let dewPoint, humidity, pressure, windSpeed: Double
    let windGust, windBearing, cloudCover, uvIndex, visibility: Double
}
...