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) 的风力数据。我得到 jsonresponse
到 Any
"list"。但是我无法获取风力数据。我得到 error
"Value of type 'Any' has no subscripts".
此外,我不明白如何分别获取 dt=1587643200
和 dt=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)
从 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) 的风力数据。我得到 jsonresponse
到 Any
"list"。但是我无法获取风力数据。我得到 error
"Value of type 'Any' has no subscripts".
此外,我不明白如何分别获取 dt=1587643200
和 dt=1587654000
的风数据。
if let list = jsonresponse["list"] as? Any {
let wind = list["wind"] as? [String : Any],
print(wind)
}
这是一个超级简单的示例,这个
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)