简体   繁体   English

使用 Codable 解析 JSON 给我 nil - Swift

[英]Parsing JSON using Codable giving me nil - Swift

I am trying to parse JSON data.我正在尝试解析 JSON 数据。 Here is the model:这是 model:

struct WeeklyForecastResponse: Codable {
    var cod: String
    var message, cnt: Int
    var list: [List]
    var city: City


// MARK: - City
struct City: Codable {
    var id: Int
    var name: String
    var coord: Coord
    var country: String
    var population, timezone, sunrise, sunset: Int
}

// MARK: - Coord
struct Coord: Codable {
    var lat, lon: Double
}

// MARK: - List
struct List: Codable {
    var dt: Int
    var main: MainClass
    var weather: [Weather]
    var clouds: Clouds
    var wind: Wind
    var sys: Sys
    var dtTxt: String
    var snow, rain: Rain?

    enum CodingKeys: String, CodingKey {
        case dt, main, weather, clouds, wind, sys
        case dtTxt = "dt_txt"
        case snow, rain
    }
}

// MARK: - Clouds
struct Clouds: Codable {
    var all: Int
}

// MARK: - MainClass
struct MainClass: Codable {
    var temp, tempMin, tempMax: Double
    var pressure, seaLevel, grndLevel, humidity: Int
    var tempKf: Double

    enum CodingKeys: String, CodingKey {
        case temp
        case tempMin = "temp_min"
        case tempMax = "temp_max"
        case pressure
        case seaLevel = "sea_level"
        case grndLevel = "grnd_level"
        case humidity
        case tempKf = "temp_kf"
    }
}

// MARK: - Rain
struct Rain: Codable {
    var the3H: Double

    enum CodingKeys: String, CodingKey {
        case the3H = "3h"
    }
}

// MARK: - Sys
struct Sys: Codable {
    var pod: Pod
}

enum Pod: String, Codable {
    case d = "d"
    case n = "n"
}



// MARK: - Weather
struct Weather: Codable {
    var id: Int
    var main: MainEnum
    var weatherDescription, icon: String

    enum CodingKeys: String, CodingKey {
        case id, main
        case weatherDescription = "description"
        case icon
    }
}

enum MainEnum: String, Codable {
    case clear = "Clear"
    case clouds = "Clouds"
    case rain = "Rain"
    case snow = "Snow"
}

// MARK: - Wind
struct Wind: Codable {
    var speed: Double
    var deg: Int
}
}

The URL is api.openweathermap.org/data/2.5/forecast?lat=42.33&lon=-84.04&APPID=0729d39986bfdd23470f485457a04c6d&units=Imperial URL 是api.openweathermap.org/data/2.5/forecast?lat=42.33&lon=-84.04&APPID=0729d39986bfdd23470f485457a04c6d&units=Imperial

And here is the actual parsing这是实际的解析


            guard let url = URL(string: fullURL) else {
                print("Error getting the URL")
                return
            }
            URLSession.shared.dataTask(with: url) {
                (data, resp, err) in

                DispatchQueue.main.async {
                    do {
                        let decoder = JSONDecoder()
                        decoder.keyDecodingStrategy = .convertFromSnakeCase

                        let json = try decoder.decode(WeeklyForecastResponse.self, from: data!)

                        self.fiveDayWeatherData = [json]
                        self.temp = json.list[0].main.temp
                    }
                    catch {
                        print(error)
                    }
                }
            }.resume()

        }

I am getting this error: Fatal error: Unexpectedly found nil while unwrapping an Optional value: file.我收到此错误:致命错误:在展开可选值时意外发现 nil:文件。 Anyone know why?有谁知道为什么? I am pretty sure my model is correct, and the URL works properly.我很确定我的 model 是正确的,并且 URL 工作正常。 I get the error on the decode line.我在解码线上得到错误。

You are force unwrapping data so its likely you don't have a real response.您正在强制解包data ,因此您可能没有真正的响应。 You should be handling and checking for the error first, then unwrapping the data.您应该首先处理和检查错误,然后解包数据。 Are you sure you have arbitrary loads on for app transport security?您确定您对应用程序传输安全性有任意负载吗? because the URL you gave definitely returns data.因为您提供的 URL 肯定会返回数据。

URLSession.shared.dataTask(with: url) { [weak self] (data, resp, err) in
  if let error = err {
    return print(error.localizedDescription)
  }
  guard let data = data else {
    return print("No data")
  }
  let decoder = JSONDecoder()
  decoder.keyDecodingStrategy = .convertFromSnakeCase
  switch Result(catching: { try decoder.decode(WeeklyForecastResponse.self, from: data) }) {
  case .success(let json):
    DispatchQueue.main.async { [weak self] in
      self?.fiveDayWeatherData = [json]
      self?.temp = json.list[0].main.temp
    }
  case .failure(let error):
    print(error.localizedDescription)
  }
}.resume()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM