我想使用JSON获取天气信息,但出现错误:由于格式不正确,无法读取数据。
错误'看来您的帖子大部分是代码;请添加更多详细信息。”在stackoverflow中。尽管我简短地描述了我的问题,但仍希望得到我的解释:/
tnoremap <Esc><Esc> <C-\><C-n>
API响应就是这样:
override func viewDidLoad() {
super.viewDidLoad()
let url = "https://api.openweathermap.org/data/2.5/weather?q=bursa,tr&appid=00f63a1cff271776651468c0204c422c"
getData(from: url)
}
private func getData (from url : String){
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data , response , error in
guard let data = data , error == nil else {
print ("birşeyler ters gitti")
return
}
var main : Response?
do {
main = try JSONDecoder().decode(Response.self , from: data)
} catch{
print ("ERROR IS HERE!!! \(error.localizedDescription)")
}
guard let json = main else {
return
}
print (json.weather)
})
task.resume()
}}
struct Response : Codable {
let weather : myResult
let status : String
}
struct myResult : Codable {
let main : String
let description : String
let icon : String
}
答案 0 :(得分:1)
首先,error.localizedDescription
旨在为用户显示信息。它对于调试没有用。如果将其替换为error
:
} catch {
print ("ERROR IS HERE!!! \(error)") // <- remove .localizedDescription
}
您将获得更多详细信息:
这里有错误!!! typeMismatch(Swift.Dictionary
, Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue: “ weather”,intValue:nil)],debugDescription:“预期解码 Dictionary ,但是找到了一个数组。”,底层错误: 零))
要解决此问题,您需要将weather
声明为数组:
let weather: [myResult]
我还建议您将myResult
替换为Weather
(或至少大写的MyResult
),因为这样会更易读:
struct Weather: Codable {
let main: String
let description: String
let icon: String
}
此外,在您提供的JSON响应中,没有status
字段,因此您可能需要将其从Response
类中删除(或使其可选)。
如果您想在响应中添加更多字段,请根据JSON结构声明它们。例如。如果您想添加humidity
和temperature
,则可以执行以下操作:
struct Response: Codable {
...
let main: Main
}
struct Main: Codable {
let temp: Double
let humidity: Double
}
要使用更具可读性的代码,可以使用CodingKeys
-然后变量名可以独立于JSON变量。
struct Main: Codable {
enum CodingKeys: String, CodingKey {
case temperature = "temp"
case humidity
}
let temperature: Double
let humidity: Double
}
总结一下,您的Response
可能看起来像这样:
struct Response: Codable {
let weather: [Weather]
let main: Main
// alternatively declare `status` optional
// let status: String?
}
struct Weather: Codable {
let main: String
let description: String
let icon: String
}
struct Main: Codable {
enum CodingKeys: String, CodingKey {
case temperature = "temp"
case humidity
}
let temperature: Double
let humidity: Double
}