JSONDecoder не может декодировать массив, но может декодировать строку - PullRequest
1 голос
/ 24 апреля 2020

У меня есть структура, которую я хотел бы проанализировать с Json:

struct Subsidiary: Decodable {
    let id: Int?
    let subsidiary_ref: String?
    let name: String?
    let address: String?
}

Я пытаюсь проанализировать ее следующим образом:

let sub: [Subsidiary] = try! JSONDecoder().decode([Subsidiary].self, from: data)

, где данные типа данных из

session.dataTask(with: urlRequest) { (data, response, error) in

и это дает мне ошибку

Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a string/data instead.", underlyingError: nil))

Если я делаю это так:

let sub: String = try! JSONDecoder().decode(String.self, from: data)

это работает, и это дает мне сына

[
   {"id": 5913, "subsidiary_ref": "0000159", "name": "Mercator Hipermarket Koper", "address": "Poslov.98-Koper,Dolinska C", "city": "Koper", "coordinates_x": null, "coordinates_y": null, "phone_number": "+386 56-636-800", "frequency": "A", "channel": "Food", "subchannel": "Hypermarket", "customer": 7, "day_planned": true, "badge_visible": true, "open_call": true, "number_of_planned": 13, "number_of_calls": 22, "last_call_day": 3, "notes": " notesi ki ne smejo nikoli zginiti bla marko bdsa"},
    {"id": 5870, "subsidiary_ref": "0000773", "name": "Kompas Shop Pe Ferneti?i", "address": "Partizanska 150", "city": "Se?ana", "coordinates_x": null, "coordinates_y": null, "phone_number": "+386 57-380-636", "frequency": "A", "channel": "Food", "subchannel": "Supermarket", "customer": 17, "day_planned": true, "badge_visible": true, "open_call": true, "number_of_planned": 13, "number_of_calls": 1, "last_call_day": 1, "notes": null},...
]

Что не так с моим кодом?

РЕДАКТИРОВАТЬ:

Я выясняю, что если я создаю переменную string, а затем преобразовываю это строковое значение в данные, это работает даже с Subsidiary struct.

Так что с переменной data что-то должно быть не так.

1 Ответ

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

Тот факт, что вы можете декодировать String.self и получить напечатанный JSON, означает, что root из JSON является строкой. JSON, который вы получили в текстовом виде, вероятно, выглядит следующим образом:

"[\r\n   {\"id\": 5913, \"subsidiary_ref\": \"0000159\", \"name\": \"Mercator Hipermarket Koper\", \"address\": \"Poslov.98-Koper,Dolinska C\", \"city\": \"Koper\", \"coordinates_x\": null, \"coordinates_y\": null, \"phone_number\": \"+386 56-636-800\", \"frequency\": \"A\", \"channel\": \"Food\", \"subchannel\": \"Hypermarket\", \"customer\": 7, \"day_planned\": true, \"badge_visible\": true, \"open_call\": true, \"number_of_planned\": 13, \"number_of_calls\": 22, \"last_call_day\": 3, \"notes\": \" notesi ki ne smejo nikoli zginiti bla marko bdsa\"}\r\n]"

Обратите внимание, что фактический JSON, который вы хотите, помещается в "" с, поэтому все специальные символы экранируются.

Веб-сервис очень странным образом передал JSON ...

Чтобы декодировать действительные данные JSON, сначала нужно получить строку, а затем повернуть введите в Data, затем снова декодируйте Data:

// nil handling omitted for brevity
let jsonString = try! JSONDecoder().decode(String.self, from: data)
let jsonData = jsonString.data(using: .utf8)!
let sub = try! JSONDecoder().decode([Subsidiary].self, from: jsonData)

Конечно, лучшее решение - это исправить бэкэнд.

...