如何在swift4中从复杂的json解析并获取数据?

时间:2018-12-01 14:47:29

标签: json parsing codable decodable swift4.2

我需要解析名为weather.json的json文件的帮助。
weather.json

{
  "weatherinfo": {
        "local": [
          {
            "country": "Korea",
            "weather": "rainy",
            "temperature": "20"
          },
          {
            "country": "US",
            "weather": "sunny",
            "temperature": "30"
          }
        ]
  }
}

这是我的代码

struct Weather: Decodable {
    var weatherInfo: WeatherInfo?
}

struct WeatherInfo: Decodable {
    let local: [Local]?
}

struct Local: Decodable {
    let country: String?
    let weather: String?
    let temperature: String?
}

func viewDidLoad() in UIViewController

let decoder = JSONDecoder()
guard let path: String = Bundle.main.path( forResource: "weather", ofType: "json") else { return }
let jsonURL = URL(fileURLWithPath: path)
URLSession.shared.dataTask(with: jsonURL) { (data, response, error) in
    guard let data = data else { return }
    print("pass1")
    do {
        let weather = try decoder.decode(Weather.self, from: data)
        print("parsing pass..")
        print(weather)  // Weather(weatherInfo: nil)
        print(weather.weatherInfo?.local?[0].country)  // nil
    } catch let jsonErr{
        print("Error: \(jsonErr)")
    }
}.resume()

我成功解析了,但是无法从天气常数中获取数据。.
如何从该json文件中获取国家/地区值? 有人可以修复我的代码吗?..

1 个答案:

答案 0 :(得分:1)

首先URLSession读取捆绑软件中的文件是过分的。只需获取Data

所有第二个都声明所有非可选内容,因为您清楚地知道所有键均可用

struct Weather: Decodable {
    let weatherinfo: WeatherInfo // note the lowercase spelling
}

struct WeatherInfo: Decodable {
    let local: [Local]
}

struct Local: Decodable {
    let country: String
    let weather: String
    let temperature: String
}

国家/地区位于local中的weatherInfo数组中

let url = Bundle.main.url(forResource: "weather", withExtension: "json")!
let data = try! Data(contentsOf: url)
let result = try! JSONDecoder().decode(Weather.self, from: data)
for location in result.weatherinfo.local {
    print("In \(location.country) the weather is \(location.weather) and the temperature is \(location.temperature) degrees")
}