Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am trying to parse a response using the
JSONDecoder
. If there is value for the corresponding key then it goes well, but if there is null value for a key then it fails to compile with the following error.
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}
here is the Shipment class that i defied
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)
_ = 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)
Here is the json
"ItemId": "8af66c87-9099-42a7-8a34-39def02160ac",
"VehicleName": null,
"VehicleNumber": null
Expected value is string but we are getting null
in the response. So the decoder throws an error if it's going to decode a null
value to a non-optional type. So, handle it by making the empty string in the parameters.
Model code:
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 parsing:
let data = """
"ItemId": "8af66c87-9099-42a7-8a34-39def02160ac",
"VehicleName": null,
"VehicleNumber": null
""".data(using: String.Encoding.utf8)!
let jsonData = try JSONDecoder().decode(ShipmentResponse.self, from: data)
print("\(jsonData.itemId) \(jsonData.vehicleNumber)")
} catch let error {
print(error)
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.