我正在使用Xcode 10.1和Swift 4.2。当我尝试将JSON响应转换为Codable类时,它给出了一个错误Expected to decode Array<Any> but found a string/data instead.
我的实际JSON响应来自API。
{
"d": "[{\"Data\":{\"mcustomer\":[{\"slno\":1000000040.0,\"fstname\":null}]},\"Status\":true}]"
}
我的模特就是这样
class MainData: Codable{
var d: [SubData]
}
class SubData : Codable {
var Data : Customer
var Status : Bool?
}
class Customer : Codable {
var mcustomer : [Detail]
}
class Detail : Codable {
var slno : Double?
var fstname : String?
}
我正在使用JSONDecoder()对此模型进行解码
let decoder = JSONDecoder()
let deco = try decoder.decode(MainData.self, from: data)
但是,我无法将此Json解码为我的模型。
答案 0 :(得分:1)
您的API错误。您在json中的数组不应在其两端加上引号。否则,您将声明键"d"
的值为字符串
"[...]"
[...]
建议:
Data
属性将导致与Data
类型的混淆。要在解码时重命名,可以使用CodingKeys
Decodable
协议struct
代替class
答案 1 :(得分:0)
顶级JSON对象是具有键“ d”和 string 值的字典,代表另一个JSON对象(有时称为“嵌套JSON”)。如果无法更改服务器API,则必须分两个步骤进行解码:
结合罗伯特(Robert)关于命名CodingKeys
并使用struct
的建议,它看起来像这样:
struct MainData: Codable {
let d: String
}
struct SubData : Codable {
let data : Customer
let status : Bool
enum CodingKeys: String, CodingKey {
case data = "Data"
case status = "Status"
}
}
struct Customer : Codable {
let mcustomer : [Detail]
}
struct Detail : Codable {
let slno : Double
let fstname : String?
}
do {
let mainData = try JSONDecoder().decode(MainData.self, from: data)
let subData = try JSONDecoder().decode([SubData].self, from: Data(mainData.d.utf8))
print(subData)
} catch {
print(error)
}
答案 2 :(得分:0)
要使您的解决方案正常工作,JSON响应必须采用以下格式
let json = """
{
"d": [
{
"Data": {
"mcustomer": [
{
"slno": 1000000040,
"fstname": null
}
]
},
"Status": true
}
]
}
"""
但是,正如您所看到的,您得到的JSON响应与您期望的完全不同。您需要要求更改响应,或者需要更改模型。