JSONDecoder无法解码Array但可以解码String

我有一个要从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},...
]

我的代码有什么问题?

编辑:

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.

评论
  • 爱上ni
    爱上ni 回复

    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.

    Web服务以非常奇怪的方式提供了JSON ...

    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)
    

    当然,最好的解决方案是修复后端。