使用 Swift 解码包裹在字典中的 JSON 数组 5

Decoding JSON array wrapped inside dictionary using Swift 5

{
  "records": [
    {
      "id": 1,
      "customers_name": "Acme 1"
    },
    {
      "id": 2,
      "customers_name": "Acme2"
    }    
  ]
}

这是我非常简单的 JSON 方案,但我无法让 JSONDecoder() 工作。 我的错误代码是:

Expected to decode Array but found a dictionary instead.

这是我目前正在使用的两个文件:

Customer.swift

struct Customer: Decodable, Identifiable {

    public var id: String
    public var customers_name: String

    enum CodingKeys: String, CodingKey {
       case id = "id"
       case customers_name = "customers_name"
    }

    init(from decoder: Decoder) throws{
        let container = try decoder.container(keyedBy: CodingKeys.self)
            id = try container.decode(String.self, forKey: .id)
            customers_name = (try container.decodeIfPresent(String.self, forKey: .customers_name)) ?? "Unknown customer name"
    }
}

CustomerFetcher.swift

import Foundation

public class CustomerFetcher: ObservableObject {
    @Published var customers = [Customer]()

    init(){
        load()
    }

    func load() {
        let url = URL(string: "https://somedomain.com/customers.json")!

        URLSession.shared.dataTask(with: url) {(data,response,error) in
            do {
                if let d = data {
                    print(d)
                    let decodedLists = try JSONDecoder().decode([Customer].self, from: d)
                    DispatchQueue.main.async {
                        self.customers = decodedLists
                    }
                } else {
                    print("No Data")
                }
            } catch {
                print (error)
            }

        }.resume()

    }
}

我相信是因为这个嵌套的 JSON 结构并尝试了很多东西,但仍然无法正常工作。

非常感谢,如果有人能帮助我!

您忘记了包装对象:

struct RecordList<T: Decodable>: Decodable {
    let records: [T]
}


let decodedLists = try JSONDecoder().decode(RecordList<Customer>.self, from: d)
DispatchQueue.main.async {
    self.customers = decodedLists.records
}

另请注意,Customer 可以简化为:

struct Customer: Decodable, Identifiable {
   public var id: String
   public var customersName: String

   enum CodingKeys: String, CodingKey {
      case id
      case customersName = "customers_name"
   }
}

您还可以将 JSONDecoder 设置为自动将下划线转换为驼峰式大小写。那么你甚至不需要 CodingKeys.