我的问题: 我使用网站 API - https://www.themealdb.com/api.php .
我想获取所有产品的列表。为此,链接是 https://www.themealdb.com/api/json/v1/1/categories.php
在我的代码中,我创建了一个结构:
struct Category: Decodable {
var idCategory: Int?
var strCategory: String?
var strCategoryDescription: String?
var strCategoryThumb: String?
}
然后我尝试到达该地址并获取数据。我可以将传入的数据转换为 JSON。它有效。
接下来,我想把数据转换成一个结构数组。
func load(url: String, completion: @escaping (_ objects: [Category])->()) {
guard let url = URL(string: url) else { return }
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do {
//let json = try? JSONSerialization.jsonObject(with: data, options: [])
//print("JSONSerialization" + "\(json)")
let object = try JSONDecoder().decode([Category].self, from: data)
print("JSONDecoder" + "\(object)")
completion(object)
} catch {
print(error.localizedDescription)
}
}.resume()
}
但在这一行中,我在控制台中收到错误消息:
The data couldn’t be read because it isn’t in the correct format.
可能是我的结构有误。我无法处理这个问题。
最佳答案
有两个错误。
实际错误
Type 'Array' mismatch: Expected to decode Array but found a dictionary instead.
表示您正在忽略根对象,即键为
categories
的字典
key
<id
的值是String
而不是Int
,注意 JSON 中的双引号
将所有结构成员声明为非可选 常量,因为 JSON 提供了字典中的所有键。并请将可怕的字典键映射到更有意义的成员名称。
并在 Decodable
捕获 block 中打印所有 error
和 never .localizedDescription
。
struct Response: Decodable {
let categories: [Category]
}
struct Category: Decodable {
let id: String
let name: String
let description: String
let thumbnailURL: URL
private enum CodingKeys: String, CodingKey {
case id = "idCategory"
case name = "strCategory"
case description = "strCategoryDescription"
case thumbnailURL = "strCategoryThumb"
}
}
func load(url: String, completion: @escaping ([Category]) -> Void) {
guard let url = URL(string: url) else { return }
let session = URLSession.shared
session.dataTask(with: url) { (data, _, error) in
if let error = error { print(error); return }
do {
let response = try JSONDecoder().decode(Response.self, from: data!)
print("JSONDecoder", response)
completion(response.categories)
} catch {
print(error)
completion([])
}
}.resume()
}
关于ios - 从 JSON 获取对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56259908/