I have a JSON with an array of values:
[
{ "tag": "Foo", … },
{ "tag": "Bar", … },
{ "tag": "Baz", … },
]
I want to decode this array into an array of structs where the particular type depends on the tag:
protocol SomeCommonType {}
struct Foo: Decodable, SomeCommonType { … }
struct Bar: Decodable, SomeCommonType { … }
struct Baz: Decodable, SomeCommonType { … }
let values = try JSONDecoder().decode([SomeCommonType].self, from: …)
How do I do that? At the moment I have this slightly ugly wrapper:
struct DecodingWrapper: Decodable {
let value: SomeCommonType
public init(from decoder: Decoder) throws {
let c = try decoder.singleValueContainer()
if let decoded = try? c.decode(Foo.self) {
value = decoded
} else if let decoded = try? c.decode(Bar.self) {
value = decoded
} else if let decoded = try? c.decode(Baz.self) {
value = decoded
} else {
throw …
}
}
}
And then:
let wrapped = try JSONDecoder().decode([DecodingWrapper].self, from: …)
let values = wrapped.map { $0.value }
Is there a better way?