JSONDecoder 类型不合适。代码 3840

JSONDecoder type is not appropriate. Code 3840

我正在尝试呼叫 Zomato API(类别)。我最终收到有关 dataCorrupted 和代码 3840 的错误。

我很确定我在 JSONDecoder().decode(type:, from:) 中的 "type" 不正确,或者我的类别结构设置不正确。

我的 API 电话:

let baseURL = URL(string: "https://developers.zomato.com/api/v2.1/")
let categoryURL = baseURL?.appendingPathComponent("categories")
var request = URLRequest(url: categoryURL!)
request.addValue("myAPIKey", forHTTPHeaderField: "user-key")
request.addValue("application/json", forHTTPHeaderField: "Accept")

URLSession.shared.dataTask(with: baseURL!) { (data, response, err) in
   guard let data = data else {return}

   do {
     let courses =  try JSONDecoder().decode([Categories].self, from: data)
     print(courses)
   } catch let jsonErr {
        print(jsonErr)
   }
}.resume()

我的结构:

struct Categories: Codable{
    var id: Int?
    var name: String?   
}
{
    "categories": [
        {
            "categories": {
                "id": 1,
                "name": "Delivery"
            }
        },
        {
            "categories": {
                "id": 2,
                "name": "Dine-out"
            }
        }
   ]
}

您需要如下声明您的数据类型,

struct Response: Codable {
    let categories: [Category]
}

struct Category: Codable {
    let categories: Categories
}

struct Categories: Codable {
    let id: Int
    let name: String
}

URLSession.shared.dataTask(with: baseURL!) { (data, response, err) in
   guard let data = data else {return}

   do {
     let courses =  try JSONDecoder().decode(Response.self, from: data)
     print(courses)
   } catch let jsonErr {
        print(jsonErr)
   }
}.resume()

您可以随时将 JSON 放在 app.quicktype.io 处以获得正确的数据类型。

let courses = try JSONDecoder().decode([String: [[String: Categories]]].self, from: data)

print(courses["categories"]![0]["categories"]?.name)  // prints Optional("Delivery") base on your json    

let categoriesAsArray = (courses["categories"].map { [=10=] })?.map { [=10=]["categories"] }

正如@vadian 指出的那样,问题来自您的 API。

这就是您的 API 应该为您的代码提供的答案:

[
    {
            "id": 1,
            "name": "Delivery"
    },
    {
            "id": 2,
            "name": "Dine-out"
    }
]