简体   繁体   中英

Values of Array of struct are nil

I am pretty new to Swift and as an exercise I try to create an App with Swift 5, which should show you the Weather at a Location you searched for.

Right now I am trying to implement a function that can turn a local JSON file in a struct I am using. The JSON file is located at the same directory as all the other files.

The JSON for testing purposes looks like this:

[
{
  "id": 833,
  "name": "Ḩeşār-e Sefīd",
  "state": "",
  "country": "IR",
  "coord": {
    "lon": 47.159401,
    "lat": 34.330502
  }
},
{
  "id": 2960,
  "name": "‘Ayn Ḩalāqīm",
  "state": "",
  "country": "SY",
  "coord": {
    "lon": 36.321911,
    "lat": 34.940079
  }
}
]

The struct:

struct Root: Codable {
    let jsonWeather: [JsonWeather]?
}

struct JsonWeather: Codable {
    let id: Int
    let name: String
    let state: String
    let country: String
    let coord: Coord

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case name = "name"
        case state = "state"
        case country = "country"
        case coord = "coord"
    }
}

The function that i am working on:

func loadJson(fileName: String) -> Void{
    if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
        do {
            let data = try Data(contentsOf: url)
            let jsonData = try JSONDecoder().decode(Array<Root>.self, from: data)
            print(type(of: jsonData)) // Array<Root>
            print(jsonData) // [WeatherApp.Root(jsonWeather: nil), WeatherApp.Root(jsonWeather: nil)]
        } catch {
            print("error:\(error)")
        }
    }
}

After all I wanted to see how the result looks like and I noticed that each jsonWeather in Root is nil

So in the end I understand that the values are nil because I allow them to be nil by setting an optional in the Root struct, but I dont quite understand why they are turning nil because there is data given. Also I don't know how I would implement it without being an optional.

This is my first time using JSONDecoder and Optionals in Swift. Could anyone point out what I did wrong (or understood wrong) and how to fix this issue

Since your JSON is just of array of objects, you don't need a top-level struct like Root .

Get rid of your Root struct, and just decode an array of JsonWeather s:

let jsonData = try JSONDecoder().decode([JsonWeather].self, from: data)

(Note that there is no difference between [JsonWeather].self and Array<JsonWeather>.self - I just chose to do it this way since it's shorter.)

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.

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