在Swift上解码JSON

f45qwnt8  于 2023-01-04  发布在  Swift
关注(0)|答案(1)|浏览(155)

在过去的几天里,我一直试图解码一个JSON文件,通过一个uikit应用程序,但不断失败,无论我试图这样做。有人能帮我吗?
这是我的解码函数:

override func viewDidLoad() {
        super.viewDidLoad()
        cidadelabel.text = city!
        downloadJSON {
            print("success")
        }
        print(result.main?.temp!)
        // var temperatura = result?.main?.temp
        // temperatura = temperatura! - 273.15
        // temperatureLabel.text = "\(String(temperatura!))°C"
    }
    
    func downloadJSON(completed: @escaping () -> ()){
        let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?appid=******d&q=" + city!)
        URLSession.shared.dataTask(with: url!) {
            data, response, error in
            if error == nil{
                do{
                    print(data!)
                    print(response!)
                    
                    self.result = try JSONDecoder().decode(Response.self, from: data!)
                    
                    DispatchQueue.main.async {
                        completed()
                    }
                }
                catch {
                    print("error fetching data from the api")
                    print(String(describing: error))
                }
            }
        }.resume()
    }

这是我的类接收JSON:

import Foundation

struct Response: Codable {
    
    var coord: Coord?
    var weather: [WeatherBase]?
    var main: Main?
    var visibility: Int?
    var wind: Wind?
    var rain: Rain?
    var clouds: Clouds?
    var dt: Int?
    var sys: Sys?
    var timezone: Int?
    var id: Int?
    var name: String?
    var cod: Int?

}

struct Coord: Codable {
    var lon: Double?
    var lat: Double?
}

struct WeatherBase: Codable {
    var id: String { _id! }
    private var _id: String?
    var base: String?
    
    mutating func prepare() {
        _id = _id ?? UUID().uuidString
    }
}

struct Weather: Codable {
    var id: Int?
    var main: String?
    var description: String?
    var icon: String?
}

struct Main: Codable {
    var temp: Double?
    var feels_like: Double?
    var temp_min: Double?
    var temp_max: Double?
    var pressure: Int?
    var humidity: Int?
}

struct Wind: Codable {
    var speed: Double?
    var deg: Int?
}

struct Rain: Codable{
    var umh: Int?
}

struct Clouds: Codable {
    var all: Int?
}

struct Sys: Codable {
    var type: Int?
    var id: Int?
    var country: String?
    var sunrise: Int?
    var sunset: Int?
    
}

这是JSON:

{"coord":{"lon":-35.7353,"lat":-9.6658},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":302.84,"feels_like":305.59,"temp_min":302.84,"temp_max":302.84,"pressure":1011,"humidity":61},"visibility":10000,"wind":{"speed":7.2,"deg":90},"clouds":{"all":20},"dt":1672689129,"sys":{"type":1,"id":8413,"country":"BR","sunrise":1672646788,"sunset":1672692412},"timezone":-10800,"id":3395981,"name":"Maceió","cod":200}

响应是告诉我,一切都是零(可选),因为它是从API得到一个不同的结果,这是没有意义的原因,当我进入相同的链接给我正确的JSON
响应(坐标:无,天气:无,主要:无,可见性:无,风:无,雨:无,云:无,日期:无,系统:无,时区:无,编号:无,姓名:无,编码:无)

<NSHTTPURLResponse: 0x600003837c80> { URL: https://api.openweathermap.org/data/2.5/weather?appid=b**************d&q=Maceio } { Status Code: 200, Headers {
    "Access-Control-Allow-Credentials" =     (
        true
    );
    "Access-Control-Allow-Methods" =     (
        "GET, POST"
    );
    "Access-Control-Allow-Origin" =     (
        "*"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        472
    );
    "Content-Type" =     (
        "application/json; charset=utf-8"
    );
    Date =     (
        "Mon, 02 Jan 2023 21:46:06 GMT"
    );
    Server =     (
        openresty
    );
    "X-Cache-Key" =     (
        "/data/2.5/weather?q=maceio"
    );
} }
        "/data/2.5/weather?q=maceio"
    );
} }
yzxexxkh

yzxexxkh1#

首先,您应该从您的帖子中删除“您的秘密令牌”。
其次,您需要了解downloadJSON是异步函数,只有在它完成/完成之后才能使用results
下面的代码显示了如何使用带有完成处理程序的异步函数来获取weather json数据,并将其提供给viewDidLoad()中的代码。
还要注意,如果city名称不正确,解码结果时也会出错。
请注意,没有必要让Response的所有字段都是可选的,请阅读文档,找到哪个字段是可选的,然后将代码修改为可选的。

func viewDidLoad() {
    super.viewDidLoad()
    cidadelabel.text = city!
    downloadJSON { error in
        if error == nil {
            print("success")
            
            // -- here `result` are available inside this closure, after they have been fetched
            
             print(result?.main?.temp!)
             var temperatura = result?.main?.temp
             temperatura = temperatura! - 273.15
             temperatureLabel.text = "\(String(temperatura!))°C"
        } else {
            print("error: \(error)")
        }
    }
}

func downloadJSON(completed: @escaping (Error?) -> ()){
    let token = "YOUR-SECRET-TOKEN"
    if let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?appid=\(token)&q=" + city!) {
        URLSession.shared.dataTask(with: url) { data, response, error in
            if error == nil, let data = data {
                do {
                    self.result = try JSONDecoder().decode(Response.self, from: data)
                    completed(nil) // <-- no error, all good
                }
                catch {
                    completed(error)  // <-- with error
                }
            }
        }.resume()
    }
}

struct Response: Codable {
    var coord: Coord?
    var weather: [Weather]?  // <-- here
    var main: Main?
    var visibility: Int?
    var wind: Wind?
    var rain: Rain?
    var clouds: Clouds?
    var dt: Int?
    var sys: Sys?
    var timezone: Int?
    var id: Int?
    var name: String?
    var cod: Int?
}

相关问题