可解码值 String 或 Bool
Decodable value String or Bool
我目前正在使用一个设计糟糕的 JSON Api...
这 returns 始终是一个值(例如 String、Int、Double...)或 false(非空)。
使用 decodable 处理此问题的最佳方法是什么,因为 Codable 不支持 Any?
密钥可以如下所示:
{
"key": "Test",
}
或者像这样(我知道,应该是 null 而不是 false):
{
"key": false,
}
这是不可能的:
struct Object: Decodable {
let key: Any?
}
您可以创建一个通用包装器类型,如果键的值为 false
,则将 nil
分配给 Optional
值,否则它会解码该值。然后,您可以将它们包装在这个包装器中,而不是存储实际类型。
struct ValueOrFalse<T:Decodable>: Decodable {
let value:T?
public init(from decoder:Decoder) throws {
let container = try decoder.singleValueContainer()
let falseValue = try? container.decode(Bool.self)
if falseValue == nil {
value = try container.decode(T.self)
} else {
value = nil
}
}
}
struct RandomJSONStruct: Decodable {
let anInt:ValueOrFalse<Int>
let aString:ValueOrFalse<String>
}
let noValueJson = """
{
"anInt": false,
"aString": "Test"
}
"""
do {
print(try JSONDecoder().decode(RandomJSONStruct.self, from: noValueJson.data(using: .utf8)!))
} catch {
print(error)
}
我有同样的情况,ID 可以是 Int 或 String
class MyClass: Codable {
let id: Int?
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
do {
let stringId = try values.decodeIfPresent(String.self, forKey: .id)
id = Int(stringId ?? "0")
} catch {
id = try values.decodeIfPresent(Int.self, forKey: .id)
}
}
}
在 required init(from decoder: Decoder) throws
我有另一个 do try 块,我在其中转换它
我目前正在使用一个设计糟糕的 JSON Api... 这 returns 始终是一个值(例如 String、Int、Double...)或 false(非空)。
使用 decodable 处理此问题的最佳方法是什么,因为 Codable 不支持 Any?
密钥可以如下所示:
{
"key": "Test",
}
或者像这样(我知道,应该是 null 而不是 false):
{
"key": false,
}
这是不可能的:
struct Object: Decodable {
let key: Any?
}
您可以创建一个通用包装器类型,如果键的值为 false
,则将 nil
分配给 Optional
值,否则它会解码该值。然后,您可以将它们包装在这个包装器中,而不是存储实际类型。
struct ValueOrFalse<T:Decodable>: Decodable {
let value:T?
public init(from decoder:Decoder) throws {
let container = try decoder.singleValueContainer()
let falseValue = try? container.decode(Bool.self)
if falseValue == nil {
value = try container.decode(T.self)
} else {
value = nil
}
}
}
struct RandomJSONStruct: Decodable {
let anInt:ValueOrFalse<Int>
let aString:ValueOrFalse<String>
}
let noValueJson = """
{
"anInt": false,
"aString": "Test"
}
"""
do {
print(try JSONDecoder().decode(RandomJSONStruct.self, from: noValueJson.data(using: .utf8)!))
} catch {
print(error)
}
我有同样的情况,ID 可以是 Int 或 String
class MyClass: Codable {
let id: Int?
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
do {
let stringId = try values.decodeIfPresent(String.self, forKey: .id)
id = Int(stringId ?? "0")
} catch {
id = try values.decodeIfPresent(Int.self, forKey: .id)
}
}
}
在 required init(from decoder: Decoder) throws
我有另一个 do try 块,我在其中转换它