json - Swift:JSONDecoder 从 API 返回 nil
问题描述
目前正在通过一个从 OpenWeatherMap API 获取和解码数据的应用程序工作,目前我已经完成了所有工作,除了让解码器返回一些东西。目前,解码器返回 nil,但是,我从 API 调用中获取数据字节。我不确定可能是什么问题。我已经根据层次结构设置了 ViewModel 结构。OPW API JSON 数据似乎是字典键:值对集合类型的格式,键用引号引起来,是不是我的解码器因为引号而没有找到必要的信息?
获取和解码 API 调用...
@IBAction func saveCityButtonPressed() {
if let city = cityNameTextField.text {
let weatherURL = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(city)&APPID=8bad8461edbaf3ff50aa2f2fd8ad8a71&units=imperial")!
let weatherResource = Resource<WeatherViewModel>(url: weatherURL) { data in
let weatherVM = try? JSONDecoder().decode(WeatherViewModel.self, from: data)
return weatherVM
}
Webservice().load(resource: weatherResource) { result in
}
}
}
视图模型
struct WeatherListViewModel {
private var weatherViewModels = [WeatherViewModel]()
}
struct WeatherViewModel: Decodable {
let name: String
let main: TemperatureViewModel
}
struct TemperatureViewModel: Decodable {
let temp: Double
let temp_min: Double
let temp_max: Double
}
JSON数据示例:
{
"coord":{
"lon":-0.13,
"lat":51.51
},
"weather":[
{
"id":300,
"main":"Drizzle",
"description":"light intensity drizzle","icon":"09d"
}
],
"base":"stations",
"main":{
"temp":280.32,
"pressure":1012,
"humidity":81,
"temp_min":279.15,
"temp_max":281.15
},
"visibility":10000,
"wind":{
"speed":4.1,
"deg":80
},
"clouds":{
"all":90
},
"dt":1485789600,
"sys":{
"type":1,
"id":5091,
"message":0.0103,
"country":"GB",
"sunrise":1485762037,
"sunset":1485794875
},
"id":2643743,
"name":"London",
"cod":200
}
解决方案
通过生成JSONDecoder().decode
可选 ( try?
) 的结果,您可以确保nil
在解码出错时得到结果。您可以通过实施适当的 catch 块来快速捕获与解码相关的问题。例如:
do {
let decoder = JSONDecoder()
let messages = try decoder.decode(WeatherViewModel.self, from: data)
print(messages as Any)
} catch DecodingError.dataCorrupted(let context) {
print(context)
} catch DecodingError.keyNotFound(let key, let context) {
print("Key '\(key)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch DecodingError.valueNotFound(let value, let context) {
print("Value '\(value)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch DecodingError.typeMismatch(let type, let context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch {
print("error: ", error)
}
不是您问题的直接答案,但肯定会减少其他人了解解码的哪一部分出错的时间。
推荐阅读
- javascript - 如何使用正则表达式简化嵌套花括号?
- c++ - 如何导入GDAL lib Qt、Qt Creator?
- unit-testing - 如何在 Cgreen 的 c 文件上编译(gcc)?
- javascript - 如何使用WebdriverIo在perfecto中解决30000ms错误后仍然不可见的元素
- python - 裁剪后如何转换相对边界框?
- xquery - Marklogic:如何使用正则表达式搜索文档?
- reactjs - 当开始在输入中写入时,只出现“正在加载”而不是位置下拉 - react-places-autocomplete
- c# - Unity2D“Input.GetKeyDown 不再工作
- c# - 如何在屏幕上显示数据并刷新这些数据?
- vb.net - 使用线程处理简单的任务有意义吗?