Reputation: 55
I'm trying to override how JSONDecoder decode a data.
I tried the following:
struct Response : Decodable {
init(from decoder: Decoder) throws {
print("Hello")
}
}
let result = try JSONDecoder().decode(Response.self, from: Data())
But the init(from:)
does not get called.
Basically I want the JSONDecoder
to always success when decoding empty data to empty Response
object
Upvotes: 2
Views: 1856
Reputation: 5146
Whoever comes to this page looking for a solution to force use of INIT on decodable class you just need to use:
required init(from decoder: Decoder) throws {
Full example:
class DeviceListElement: Codable {
var firmwareVersion, deviceName: String
var status: Int
enum CodingKeys: String, CodingKey {
case firmwareVersion = "fwVer"
case deviceName
case status
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
firmwareVersion = try container.decode(String.self, forKey: .firmwareVersion)
deviceName = try container.decode(String.self, forKey: .deviceName)
status = try container.decode(Int.self, forKey: .status)
//if is optional use this: container.decodeIfPresent(String.self, forKey: .blabla)
}
}
Upvotes: -1
Reputation: 285079
An empty Data
object causes the init
method to throw the error
The given data was not valid JSON.
before "Hello" gets printed.
If you want to get an empty Response
object (assuming you don't have to call any designated initializer) catch the dataCorrupted
decoding error
struct Response : Decodable {}
var response : Response?
do {
response = try JSONDecoder().decode(Response.self, from: Data())
} catch DecodingError.dataCorrupted(let context) where (context.underlyingError as NSError?)?.code == 3840 { // "The given data was not valid JSON."
response = Response()
} catch { print(error) }
Upvotes: 4