为什么在使用JSONDecoder.decode方法时不调用Decodable的init方法?
Why Decodable's init method isn't called when using JSONDecoder.decode method?
我正在尝试覆盖 JSONDecoder 解码数据的方式。
我尝试了以下方法:
struct Response : Decodable {
init(from decoder: Decoder) throws {
print("Hello")
}
}
let result = try JSONDecoder().decode(Response.self, from: Data())
但是 init(from:)
没有被调用。
基本上我希望 JSONDecoder
在将空数据解码为空 Response
对象时总是成功
空 Data
对象导致 init
方法抛出错误
The given data was not valid JSON.
在 "Hello" 打印之前。
如果你想得到一个空的 Response
对象(假设你不必调用任何指定的初始化程序)捕获 dataCorrupted
解码错误
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) }
无论谁来到此页面寻找强制在可解码 class 上使用 INIT 的解决方案,您只需要使用:
required init(from decoder: Decoder) throws {
完整示例:
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)
}
}
我正在尝试覆盖 JSONDecoder 解码数据的方式。
我尝试了以下方法:
struct Response : Decodable {
init(from decoder: Decoder) throws {
print("Hello")
}
}
let result = try JSONDecoder().decode(Response.self, from: Data())
但是 init(from:)
没有被调用。
基本上我希望 JSONDecoder
在将空数据解码为空 Response
对象时总是成功
空 Data
对象导致 init
方法抛出错误
The given data was not valid JSON.
在 "Hello" 打印之前。
如果你想得到一个空的 Response
对象(假设你不必调用任何指定的初始化程序)捕获 dataCorrupted
解码错误
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) }
无论谁来到此页面寻找强制在可解码 class 上使用 INIT 的解决方案,您只需要使用:
required init(from decoder: Decoder) throws {
完整示例:
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)
}
}