解析 IOS 中的 Json 响应时出现 valueNotFound 错误

valueNotFound error while parsing Json response in IOS

我正在尝试使用 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: "Expected String value but found null instead.", underlyingError: nil))

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

这是我违抗的货物class

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
}

错误很明显。

Expected String value but found null instead

预期值为字符串,但我们在响应中得到 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)
}