Расшифровка массива JSON, заключенного в словарь с использованием Swift 5 - PullRequest
0 голосов
/ 02 апреля 2020
{
  "records": [
    {
      "id": 1,
      "customers_name": "Acme 1"
    },
    {
      "id": 2,
      "customers_name": "Acme2"
    }    
  ]
}

Это моя действительно простая JSON схема, но я не могу заставить JSONDecoder () работать. Мой код ошибки:

Ожидается декодировать массив, но вместо него найден словарь.

Вот мои два файла, которые я сейчас использую:

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 и перепробовал много вещей, но все еще не может заставить ее работать .

Большое спасибо, если кто-нибудь мне поможет!

1 Ответ

1 голос
/ 02 апреля 2020

Вы забываете оберточный объект:

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.

...