Как декодировать кодируемое свойство в два типа данных просто, если один из них всегда пуст? - PullRequest
0 голосов
/ 08 мая 2018

Я получаю из почтового запроса, этот JSON:

"clinic_info": {
                "city": "Querétaro",
                "state": "Querétaro",
                "country": "México",
                "phone": null,
                "ext": null,
                "coords": "20.6046089,-100.37826050000001",
                "location": "Querétaro"
            }

Но когда он пуст, JSON:

"clinic_info": []

Это приводит к ошибке: ожидается декодирование словаря, но вместо него найден массив.

Ответы [ 4 ]

0 голосов
/ 08 мая 2018

Служба, предоставляющая ответы JSON:

"clinic_info": { ... }

Где ... - допустимый объект JSON.

Но когда он пуст, вы говорите, что это выглядит так:

"clinic_info": []

Обратите внимание на [], который говорит, что это пустой массив объектов .

Возможно, вы захотите изменить ответ службы (если это возможно), так как он кажется мне непоследовательным, если он возвращает объект, когда он имеет действительные данные, и массив, если нет действительных данных.

Сообщение об ошибке, которое вы получаете, ясно:

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

Ожидается объект {}, но найден массив [].

0 голосов
/ 08 мая 2018

У класса Array есть метод для этого.

Использование typeof всегда возвращает "object".

Приведенный ниже код показывает, как использовать метод isArray() в классе Array.

const obj = {
  _array: [],
  _object: {}
}

console.log(Array.isArray(obj._array)); // true
console.log(Array.isArray(obj._object)); // false
0 голосов
/ 08 мая 2018

Вы можете сделать это, используя try, throw вот так

import Foundation

struct ClinicData: Codable {
    let clinicInfo: ClinicInfo?

    enum CodingKeys: String, CodingKey {
        case clinicInfo = "clinic_info"
    }
}

struct ClinicInfo: Codable {
    let city, state, country: String
    let coords, location: String
}

// MARK: Convenience initializers

extension ClinicData {
    init(data: Data) throws {
        self = try JSONDecoder().decode(ClinicData.self, from: data)
    }

    init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }


    func jsonData() throws -> Data {
        return try JSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}


**get clinicInfo** 

   if  let clinicData =  try? ClinicData.init(data: Data()), let clinicInfo = 
    clinicData.clinicInfo{

        }
0 голосов
/ 08 мая 2018

Это происходит потому, что decoder хочет dictionary, а ваш JSON равен array

Необходимо проверить перед decoding, что ответ JSON равен dictionary или Array и выполнить decoding соответственно.

Если вы найдете Dictionary, сделайте так

let myData = try JSONDecoder().decode(YourModel.self, from: jsonData)

Если вы найдете Array, сделайте так

let myData = try JSONDecoder().decode([YourModel].self, from: jsonData)
...