Mam JSON z tablicą wartości:Jak odkodować tablicę wartości, których typy zależą od znacznika?
[
{ "tag": "Foo", … },
{ "tag": "Bar", … },
{ "tag": "Baz", … },
]
Chcę dekodować tej tablicy do tablicy struct
s gdzie szczególny rodzaj zależy od tagu:
protocol SomeCommonType {}
struct Foo: Decodable, SomeCommonType { … }
struct Bar: Decodable, SomeCommonType { … }
struct Baz: Decodable, SomeCommonType { … }
let values = try JSONDecoder().decode([SomeCommonType].self, from: …)
jak mogę Zrób to? W tej chwili mam ten nieznacznie brzydki 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 …
}
}
}
, a następnie:
let wrapped = try JSONDecoder().decode([DecodingWrapper].self, from: …)
let values = wrapped.map { $0.value }
jest jakiś lepszy sposób?
jestem przy założeniu, że nie jesteś ten, który wysyła to json. Jedyny inny sposób, jaki mogę sobie wyobrazić, to przechowywanie słownika od napisu do typu, a następnie sprawdzanie, czy znacznik znajduje się w słowniku, jeśli tak się stanie, to otrzymasz odpowiedni typ, a następnie zainicjujesz obiekt. (Pominąłem kilka drobniejszych szczegółów, ale myślę, że macie główny pomysł). – TNguyen
Porównaj drugą część https: // stackoverflow.com/a/44473156/2976878 dla innego podejścia (nie jestem pewien, czy uznałbyś to za lepsze, czy nie, nadal używa on typu wrappera) – Hamish
@Hamish, to pytanie jest dokładnie tym, czego szukam, więc zamierzam to zamknąć jako dupek po wygaśnięciu nagrody. Dziękuję Ci! – zoul