在iOS中解析Json响应时出现valueNotFound错误

时间:2018-11-29 09:33:59

标签: ios json swift parsing jsondecoder

我正在尝试使用JSONDecoder解析响应。如果对应的键有值,那么它将很好,但是如果键的值为空,则它将无法编译,并出现以下错误。

  

valueNotFound(Swift.String,Swift.DecodingError.Context(codingPath:   [CodingKeys(stringValue:“ Results”,intValue:nil),   _JSONKey(stringValue:“ Index 0”,intValue:0),CodingKeys(stringValue:“ VehicleName”,intValue:nil)],debugDescription:“期望的字符串   值,但改为找到null。”,underlyingError:nil))

guard let obj = try? JSONDecoder().decode(ShipmentsResponse.self, from: json) else {return}

这是我所定义的货运类别

class ShipmentResponse : Codable {

    var ItemId: String = ""
    var VehicleName: String  = ""
    var VehicleNumber: String  = ""

    convenience required init(from decoder: Decoder) throws
    {
        self.init()
        let values = try decoder.container(keyedBy: CodingKeys.self)
        ItemId = try values.decode(String.self, forKey: .ItemId)

        do {
            _ = try values.decode(String.self, forKey: .VehicleName)
        } catch {
            print(error)
        }

        VehicleName = try values.decode(String.self, forKey: .VehicleName)
        VehicleNumber = try values.decode(String.self, forKey: .VehicleNumber)
    }

}

这是json

{
    "ItemId": "8af66c87-9099-42a7-8a34-39def02160ac",
    "VehicleName": null,
    "VehicleNumber": null
}

1 个答案:

答案 0 :(得分:2)

错误非常清楚。

  

期望的字符串值,但发现为空

期望值为字符串,但响应中得到null。因此,如果解码器要将null值解码为非可选类型,则会引发错误。因此,请在参数中输入空字符串来处理它。

型号代码:

class ShipmentResponse : Codable {

    var itemId: String
    var vehicleName: String
    var vehicleNumber: String

    enum CodingKeys: String, CodingKey {
        case itemId = "ItemId"
        case vehicleName = "VehicleName"
        case vehicleNumber = "VehicleNumber"
    }

    required init(from decoder: Decoder) throws {

        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.itemId = try container.decodeIfPresent(String.self, forKey: .itemId) ?? ""
        self.vehicleName = try container.decodeIfPresent(String.self, forKey: .vehicleName) ?? ""
        self.vehicleNumber = try container.decodeIfPresent(String.self, forKey: .vehicleNumber) ?? ""
    }

    func encode(to encoder: Encoder) throws {

        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(itemId, forKey: .itemId)
        try container.encode(vehicleName, forKey: .vehicleName)
        try container.encode(vehicleNumber, forKey: .vehicleNumber)
    }
}

JSON解析:

let data = """
{
    "ItemId": "8af66c87-9099-42a7-8a34-39def02160ac",
    "VehicleName": null,
    "VehicleNumber": null
}
""".data(using: String.Encoding.utf8)!

do {
    let jsonData = try JSONDecoder().decode(ShipmentResponse.self, from: data)
    print("\(jsonData.itemId) \(jsonData.vehicleNumber)")
} catch let error {
    print(error)
}