ios - 解码 JSON 时出错,Swift 4.2
问题描述
在 swift 4.2 中解码 JSON 时出现错误
预期解码 Array 但找到了字典。
我的 JSON 模型:
public struct NewsSource: Equatable, Decodable {
public let id: String?
public let name: String?
public let sourceDescription: String?
public let url: URL?
enum CodingKeys: String, CodingKey {
case id
case name
case sourceDescription = "description"
case url
}
public init(id: String,
name: String,
sourceDescription: String,
url: URL,
category: NewsCategory,
language: NewsLanguage,
country: NewsCountry) {
self.id = id
self.name = name
self.sourceDescription = sourceDescription
self.url = url
} }
我如何获取 JSON:
func fetchJSON() {
let urlString = "https://newsapi.org/v2/sources?apiKey=myAPIKey"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, _, err) in
DispatchQueue.main.async {
if let err = err {
print("Failed to get data from url:", err)
return
}
guard let data = data else { return }
print(data)
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.Sources = try decoder.decode([NewsSource].self, from: data)
self.tableView.reloadData()
} catch let jsonErr {
print("Failed to decode:", jsonErr)
}
}
}.resume()
}
解决方案
如果您查看正在返回的 JSON,它看起来像这样:
{
"status": "ok",
"sources": [{
"id": "abc-news",
"name": "ABC News",
"description": "Your trusted source for breaking news, analysis, exclusive interviews, headlines, and videos at ABCNews.com.",
"url": "https://abcnews.go.com",
"category": "general",
"language": "en",
"country": "us"
}, {
"id": "abc-news-au",
"name": "ABC News (AU)",
"description": "Australia's most trusted source of local, national and world news. Comprehensive, independent, in-depth analysis, the latest business, sport, weather and more.",
"url": "http://www.abc.net.au/news",
"category": "general",
"language": "en",
"country": "au"
},
...
虽然有一个源数组,但该数组不是根。JSON 的根是一个包含status
字符串和sources
数组的对象。这就是解码器失败的原因。
您需要定义一个额外的结构来处理这个:
struct NewsResult {
let status: String
let sources: [NewsSource]
}
然后你解码这个对象:
let sourceResult = try decoder.decode(NewsResult.self, from: data)
self.sources = sourceResult.sources
推荐阅读
- php - 如何更改我的 WooCommerce 商店页面标题背景颜色?
- c++ - 在 return 语句中嵌套条件运算符
- mysql - 使用每个帐户的最近日期的所有帐户的值总和
- c# - 如何有效地比较大量照片以找到重复项
- java - GenCollectForAllocation 是什么意思?
- q# - 访问模拟器或跟踪模拟器的调用图
- c# - 如何在 OData 中全局更改 MaxExpansionDepth 设置
- python - 在 matplotlib 中将绘图附加到 HTML 文件
- javascript - 反应:链接到另一个 html 页面上的 div
- c# - 在 EF 核心中搭建脚手架时出现 sql 连接字符串错误?