I am trying to parse JSON data. Here is the 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
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. Anyone know why? I am pretty sure my model is correct, and the URL works properly. I get the error on the decode line.
You are force unwrapping data
so its likely you don't have a real response. 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.
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.