Swift 来自 Openweathermap 的天气数据 API?

Swift weather data from Openweathermap API?

openweathermap api 开始,我得到的响应低于此值。

{
  "cod":"200",
  "message":0,
  "cnt":40,
  "list":[
     {
        "dt":1587643200,
        "main":{
           "temp":289.78,
           "feels_like":283.61,
           "temp_min":289.03,
           "temp_max":289.78,
           "pressure":1014,
           "sea_level":1014,
           "grnd_level":1010,
           "humidity":41,
           "temp_kf":0.75
        },
        "weather":[
           {
              "id":804,
              "main":"Clouds",
              "description":"overcast clouds",
              "icon":"04d"
           }
        ],
        "clouds":{
           "all":94
        },
        "wind":{
           "speed":6.75,
           "deg":2
        },
        "sys":{
           "pod":"d"
        },
        "dt_txt":"2020-04-23 12:00:00"
     },
     {
        "dt":1587654000,
        "main":{
           "temp":289.66,
           "feels_like":284.44,
           "temp_min":289.34,
           "temp_max":289.66,
           "pressure":1013,
           "sea_level":1013,
           "grnd_level":1009,
           "humidity":47,
           "temp_kf":0.32
        },
        "weather":[
           {
              "id":803,
              "main":"Clouds",
              "description":"broken clouds",
              "icon":"04d"
           }
        ],
        "clouds":{
           "all":67
        },
        "wind":{
           "speed":5.9,
           "deg":357
        },
        "sys":{
           "pod":"d"
        },
        "dt_txt":"2020-04-23 15:00:00"
     }

然后我编写下面的代码来获取任何特定白天 (dt) 的风力数据。我得到 jsonresponseAny "list"。但是我无法获取风力数据。我得到 error

"Value of type 'Any' has no subscripts".

此外,我不明白如何分别获取 dt=1587643200dt=1587654000 的风数据。

                           if let list = jsonresponse["list"] as? Any {
                               let wind = list["wind"] as? [String : Any],
                               print(wind)
                           }

这是一个超级简单的示例,这个 is similar to your problem. I would like that you learn about Codable 协议可以简化和改进您的代码,因为这种方式非常令人毛骨悚然。

let url = URL(string: "https://samples.openweathermap.org/data/2.5/history/city?id=2885679&type=hour&appid=b1b15e88fa797225412429c1c50c122a1")!
URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) in
    if let error = error {
        print(error.localizedDescription)
        return
    }

    guard let httpResponse = response as? HTTPURLResponse,
        (200...299).contains(httpResponse.statusCode) else {
            print("Error with the response, unexpected status code: \(String(describing: response))")
            return
    }

    guard let data = data else {
        return
    }

    guard let dictionaryObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
        return
    }

    guard let list = dictionaryObj["list"] as? [[String: Any]] else {

        return
    }

    if let first = list.first, let wind = first["wind"] {
        print(wind)
    }
}).resume()

如果有人进一步需要帮助,我写了一小段代码——使用 Swift Codables——来完成这件事。

请注意,我在 Swift 中使用 高阶函数来过滤和打印所需的值。如果您需要了解更多有关它们的工作原理,可以关注 this tutorial..

let urlNew = "https://samples.openweathermap.org/data/2.5/history/city?id=2885679&type=hour&appid=b1b15e88fa797225412429c1c50c122a1"
struct WeatherResponse: Codable {
    
    let message: String
    let cod: String
    let city_id: Int
    let calctime: Double
    let cnt: Int
    
    let list: [WeatherCompositeObject]
    
    struct WeatherCompositeObject: Codable {
        
        let main: WeatherMainObject
        let wind: WeatherWindObject
        let clouds: WeatherCloudObject
        let weather: [WeatherObject]
        let dt: Int
        
        struct WeatherMainObject: Codable {
            let temp: Double
            let humidity: Int
            //You can add the other parameters as needed here
        }
        
        struct WeatherWindObject: Codable {
            let speed: Double
            let deg: Double
        }
        
        struct WeatherCloudObject: Codable {
            let all: Int
        }
        
        struct WeatherObject: Codable {
            let id: Int
            let main: String
            let description: String
        }
    }
}

class ApiContentDownloader {

    func getCurrentWeather(url: String) {
        
        URLSession.shared.dataTask(with: URL(string: url)!) { data, urlResponse, error in
            
            let parser = ContentParser()
            let result = parser.parseData(data: data!)
            
            if let result = result {
                print("Weather: \(result.message)")
                print("DT values:  \(result.list.map({ [=10=].dt})) ")
                print("Wind values:  \(result.list.map({ [=10=].wind.speed})) ")
                print("Weather descriptions:  \(result.list.map({ [=10=].weather.map( {[=10=].description} )})) ")
            }
            else {
                print("Oops... Error occured")
            }
            
        }.resume()
        
    }
    
}

class ContentParser {
    
    func parseData(data: Data) -> WeatherResponse? {
       
        var result: WeatherResponse? = nil
        
        do {
            let json = try JSONDecoder().decode(WeatherResponse.self, from: data)
            result = json
        }
        catch {
            print(error.localizedDescription)
        }
        
        return result
    }
}

let downloader = ApiContentDownloader()
downloader.getCurrentWeather(url: urlNew)