1

I have a struct that I would like to parse from Json:

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

I try to parse it like:

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

where data is Data type from

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

and it gives me an error

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))

If I do it like this:

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

it works and it gives me son

[
   {"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},...
]

What is wrong with my code?

EDIT:

I figure out, that if I create a string variable, and then convert this string value to data it works even with Subsidiary struct.

So something should be wrong with the data variable.

1
  • Could you do print(String(data: data, enoding: .utf8)) I think that you have JSON Stringified, starting with double quotes and ending with them too. Commented Apr 24, 2020 at 16:23

1 Answer 1

2

The fact that you can decode a String.self and get your JSON printed means that the root of the JSON is a string. The JSON you got, in text form, probably looks like this:

"[\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]"

Note that the actual JSON you want is put in ""s, so all the special characters are escaped.

The web service has given the JSON in a very weird way...

To get the actual JSON data decoded, you need to get the string first, then turn the string into Data, then decode that Data again:

// 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)

Of course, the best solution is to fix the backend.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.