嘿,我有这个杰森的例子:
{"v":{"value1":1548303671,"value2":"invalid","value3":"invalid"}}
和模型类:
struct VersionApi: Decodable {
let data: NestedData?
let v: [String:Int?]
enum CodingKeys: String, CodingKey {
case data = "data"
case v = "v"
}
}
尝试解码时,出现以下错误消息:
debugDescription:“预期对Int进行解码,但是找到了一个字符串/数据 相反。”,底层错误:无)
我知道这意味着什么,但我不知道解决方案。
我需要一个具有整数的字典,其格式为:[String:Int?]
。我试图编写这样的自定义初始化程序:
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
data = try values.decode(NestedData, forKey: .data)
let vID: [String:Any] = try values.decode([String:Any].self, forKey: .v)
v = try values.decode([String:Int?].self, forKey: .v)
}
然后,我想浏览一下字典,如果Any
不是Int
,我希望将其设置为nil
。但这不起作用,因为没有候选人产生预期的类型:
没有“解码”候选词产生预期的上下文结果类型 '[String:任何]'
如果该值不是Int,如何将Int设置为nil?
答案 0 :(得分:0)
由于Any
不可解码,因此编译器在抱怨。您可以首先按照以下方式创建enum
(从answer开始)以对动态类型进行解码/编码,
enum BiType<L: Codable, R: Codable>: Codable {
case left(L)
case right(R)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let left = try? container.decode(L.self) {
self = .left(left)
} else if let right = try? container.decode(R.self) {
self = .right(right)
} else {
throw DecodingError
.typeMismatch(
BiType<L, R>.self,
.init(codingPath: decoder.codingPath,
debugDescription: "Expected either `\(L.self)` or `\(R.self)`"))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case let .left(left):
try container.encode(left)
case let .right(right):
try container.encode(right)
}
}
}
现在您可以更新VersionApi
以使用该类型,
struct VersionApi: Decodable {
let data: NestedData?
let v: [String: BiType<String, Int>]
enum CodingKeys: String, CodingKey {
case data = "data"
case v = "v"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
data = try values.decode(NestedData.self, forKey: .data)
v = try values.decode([String: BiType<String, Int>].self, forKey: .v)
}
}
示例
let data = """
{"v":{"value1":1548303671,"value2":"invalid","value3":"invalid"}}
""".data(using: .utf8)!
do {
let v = try JSONDecoder().decode(VersionApi.self, from: data)
v.v.values.forEach({ (type) in
switch type {
case .left(let left):
debugPrint(left)
case .right(let right):
debugPrint(right)
}
})
} catch {
debugPrint(error)
}
输出
1548303671 "invalid" "invalid"