我很好奇,有没有办法拒绝任意数据被Swift中的JSONDecoder忽略?即使手动实施
init(decoder:)
,我也看不到捕捉意外键的方法。我试过了,但在那里找不到答案。有人可以指出我正确的方向吗?例如,我可以在某处设置一个解码策略标志来帮助解决这个问题吗?
这里有一些代码来显示问题(如果
importData
被调用,预计会出现致命错误):
private struct DataRecord {
var greeting: String = "Hello"
}
// Adding Codable in an extension allows us to keep the compiler generated init().
extension DataRecord: Codable {
enum CodingKeys: CodingKey, CaseIterable {
case greeting
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(greeting, forKey: .greeting)
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
greeting = try container.decode(String.self, forKey: .greeting)
// An attempt at rejecting unrecognised keys, but allKeys doesn't include "unexpected_key"
let foundKeys = Set(container.allKeys.map { $0.stringValue })
let validKeys = Set(CodingKeys.allCases.map { $0.stringValue })
let invalidKeys = foundKeys.subtracting(validKeys)
print("found: \(foundKeys)")
print("valid: \(validKeys)")
print("invalid: \(invalidKeys)")
guard invalidKeys.isEmpty else {
fatalError("Bad Keys Found: \(invalidKeys)")
}
}
}
func importData() {
let stringData = """
{
"greeting": "Hello World!",
"unexpected_key": "This should fail!"
}
"""
let data = stringData.data(using:.utf8)!
let decoder = JSONDecoder()
let record = try! decoder.decode(DataRecord.self, from: data) // <-- this should fail
}