问题描述
我正在从JSON REST API中检索复杂的嵌套对象。
I am retrieving a complex nested object from my JSON REST API.
DocumentDraft
- uuid: String
- schema: Schema // Very complicated object with many variations
- url: String
- values: [Value]
- successors: [String]
- predecessors: [String]
Value
- key: String
- val: String? OR [String]? // <-- This is the problem
我想解决这个问题的正确方法是引入泛型
I suppose the proper way to deal with this is to introduce a generic type.
struct Value<V: Decodable>: Decodable {
let key: String
let val: V?
}
...但即使如此,值
可能是一个混合数组,所以我看不出声明 V
有什么帮助。
... but even so, values
could be a mixed array, so I do not see how declaring what V
is would help.
但是,当然,泛型类型一直沿层次结构传播,一直传播到 DocumentDraft
对象,发布者,我的API调用等。污染了否则非常干净易读的调用的整个链和对象。我只想在 Value
级别上处理此问题,然后让JSONDecoder简单地以某种方式返回两个值之一。
But then, of course the generic type propagates all the way up the hierarchy, to the DocumentDraft
object, to the publisher, to my API calls, etc. polluting the entire chain of otherwise very clean and readable calls and objects. I would like to deal with this only on the level of Value
, and let the JSONDecoder simply return one of the two somehow.
还有另一种方式来处理可选的 val
作为 String
或的两种可能性[String]
而不更改整个父对象?
Is there another way to deal with the two possibilities of the optional val
as either String
or [String]
without changing the entire parent object?
推荐答案
您可以仅使用 [String]
类型并手动实现 Decodable $的
init(from:)
函数c $ c>协议,例如:
You can achieve that using only the [String]
type and manually implementing the init(from:)
function of Decodable
protocol like this:
struct Value: Decodable {
let key: String
let val: [String]?
enum CodingKeys: String, CodingKey {
case key, val
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
key = try container.decode(String.self, forKey: .key)
do {
if let string = try container.decodeIfPresent(String.self, forKey: .val) {
val = [string]
} else {
val = nil
}
} catch DecodingError.typeMismatch {
val = try container.decodeIfPresent([String].self, forKey: .val)
}
}
}
成功解码为 String
值后,创建仅包含一个元素的字符串数组。当解码为 String
值失败时,请尝试解码为 [String]
When decoding to String
value succeeds, create an array of strings with only one element. When decoding to String
value fails, try to decode as [String]
这篇关于Swift Decodable-如何避免泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!