ios - 从 JSON 获取对象

标签 ios json swift

我的问题: 我使用网站 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。它有效。

enter image description here

接下来,我想把数据转换成一个结构数组。

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.

可能是我的结构有误。我无法处理这个问题。

最佳答案

两个错误。

  1. 实际错误

    Type 'Array' mismatch: Expected to decode Array but found a dictionary instead.

    表示您正在忽略根对象,即键为 categories

  2. 的字典
  3. key id 的值是 String 而不是 Int,注意 JSON 中的双引号

    <

将所有结构成员声明为非可选 常量,因为 JSON 提供了字典中的所有键。并请将可怕的字典键映射到更有意义的成员名称。

并在 Decodable 捕获 block 中打印所有 errornever .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/

相关文章:

ios - 使用委托(delegate)从 UIView 子类向 UIViewController 发送数据

javascript - 如何使用 ngFor 在 angular2 中加载多个子组件?

javascript - 为什么表加载的 JSON 数据 URL 最后出现在 DOM 中?

json - 提升-mongo-记录 : Empty JsonObjectField in mongo collection

ios - 查看动画有时会在零时间内执行

swift - 如何从单个设备获取两个唯一 ID

ios - Swift - 如何使用偏移选项将 UNIX 时间转换为工作日?

ios - Firebase 覆盖现有记录

ios - Swift:什么是 .swift-version 文件?

ios - 强制本地化 UIKit 等内部框架,无需重启应用程序