如何在Swift 4中获取嵌套的JSON数据

时间:2018-08-13 16:36:57

标签: ios swift xcode api openweathermap

我已经在Swift 4中为iOS制作了一个天气应用程序,我正在使用OpenWeatherMap API将JSON数据解析到该应用程序中,大部分应用程序都在工作,用户可以输入城市,并且天气显示。我具有当前的温度,当前的风速,当前的湿度,并且我试图使当前的说明生效,但无法显示它。

我想让MainLabel显示当前的天气描述,但无法正常工作。代码的顶部是来自API密钥的JSON数据,其描述位于“天气”部分。我已经尝试过MainLabel.Weather?.Description,但它会打印出整个描述,ID,Main和Icon值。我希望能对此提供指导。谢谢

这是我用来从OpenWeatherMap API解码JSON数据的结构:

JSON结构如下:

import UIKit


//Below is the JSON data from the OpenWeatherMap API


struct Coordinate : Decodable {
    let lat, lon : Double?
}

struct Weather : Decodable {
    var id : Int?
    var main, myDescription, icon : String?

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

struct Sys : Decodable {
    let type, id : Int?
    let sunrise, sunset : Date?
    let message : Double?
    let country : String?
}

struct Main : Decodable {
    let temp, tempMin, tempMax : Double?
    let pressure, humidity : Int?
}

struct Wind : Decodable {
    let speed : Double?
    let deg : Int?
}

struct MyWeather : Decodable {
    let coord : Coordinate?
    let cod, visibility, id : Int?
    let name : String?
    let base : String?
    let weather : [Weather]?
    let sys : Sys?
    let main : Main?
    let wind : Wind?
    let dt : Date?
}

下面的视图控制器:

class ViewController: UIViewController {



    @IBOutlet weak var HumidityLabel: UILabel!
    @IBOutlet weak var MainLabel: UILabel!
    @IBOutlet weak var WindLabel: UILabel!
    @IBOutlet weak var TempLabel: UILabel!
    @IBOutlet weak var LocationLabel: UILabel!
    //
    @IBOutlet weak var userValue: UITextField!

    //Assigning Labels




    override func viewDidLoad() {
        super.viewDidLoad()

            }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }




    @IBAction func GoButton(_ sender: Any) {

        let text: String = userValue.text!

        guard let APIUrl = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=" + text +  "&appid=e7b2054dc37b1f464d912c00dd309595&units=Metric") else { return }
        //API KEY

        URLSession.shared.dataTask(with: APIUrl) { data, response, error in
            guard let data = data else { return }

            let decoder = JSONDecoder()
            //Decoder

            do {
                let weatherData = try decoder.decode(MyWeather.self, from: data)

                if (self.MainLabel != nil)
                {
                    if let gmain = weatherData.weather?.description {
                        print(gmain)
                        DispatchQueue.main.async {
                            self.MainLabel.text! = String (describing: gmain)
                        }
                    }
                }

                if (self.LocationLabel != nil)
                {
                    if let gmain = weatherData.name {
                        print(gmain)
                        DispatchQueue.main.async {
                            self.LocationLabel.text! = "Current Weather in: " + String (gmain)
                        }
                    }
                }


                if (self.HumidityLabel != nil)
                {
                    if let ghumidity = weatherData.main?.humidity
                    {
                        print(ghumidity, "THIS IS HUMIDITY")
                        DispatchQueue.main.async {
                            self.HumidityLabel.text! = String (ghumidity)
                        }
                    }
                }

                if (self.WindLabel != nil)
                {
                    if let gspeed = weatherData.wind?.speed {
                        print(gspeed, "THIS IS THE SPEED")
                        DispatchQueue.main.async {
                            self.WindLabel.text! = String(gspeed) + " mph"
                        }
                    }
                }

                if (self.TempLabel != nil)
                {
                    if let ggtemp = weatherData.main?.temp {
                        print(ggtemp, "THIS IS THE TEMP")
                        DispatchQueue.main.async {
                            self.TempLabel.text! = String (ggtemp) + " c"
                        }
                    }
                }


            } catch {
                print(error.localizedDescription)
            }
            }.resume()

    }

}

1 个答案:

答案 0 :(得分:1)

停止并考虑以下几行:

let weatherData = try decoder.decode(MyWeather.self, from: data)
if let gmain = weatherData.weather?.description {

如果weatherData是MyWeather实例,则其weather[Weather],因为这是声明MyWeather的方式:

struct MyWeather : Decodable {
    // ...
    let weather : [Weather]?
    // ...
}

[Weather]不是天气。这是(天气)的数组。因此,您要的是 array description。这就是您所得到的。