Decoding a heterogeneous JSON array by a type field
custom Decodable with a discriminator.
peek the type field with a partial decode, switch on it, and decode the concrete type, wrapping each in an enum or boxed protocol value.
WHAT THIS TESTS It checks whether you understand that Swift cannot synthesize decoding into an abstract protocol and can hand-roll the discriminator pattern that real APIs require.
WHY THE NAIVE APPROACH FAILS Declaring let items: [Feedable] and expecting JSONDecoder to fill it fails because a protocol existential is not Decodable; the decoder has no way to know which concrete type to build. You must inspect the JSON and choose the type yourself.
A GOOD ANSWER COVERS Define an enum that lists the possible type discriminator values and conforms to a String raw value. Create a container keyed by the discriminator, decode just the type field, then switch on it. In each branch decode the concrete type, for example Article or Video, from the same decoder. Wrap the results so the element type is concrete: either an enum with associated values, one per kind, or a type-erased box such as a struct that stores any Feedable. To decode the whole array, decode an array of that wrapper or use a single-value container per element.
COMMON WRONG ANSWERS Decoding into a bare protocol array and expecting it to work. Forcing every type into one giant struct with all optional fields. Forgetting to handle an unknown discriminator value, which should throw a DataCorrupted or fail gracefully.
LIKELY FOLLOW-UPS How do you handle an unknown type value? Enum-with-associated-values versus type erasure, which is better? How do you re-encode this array? How does this interact with nested containers?
ONE CONCRETE EXAMPLE A feed returns mixed cards. You define enum FeedItem: Decodable with cases article(Article) and video(Video). Its init(from:) reads the type string, and on "article" decodes Article(from: decoder), on "video" decodes Video, and on anything else throws a descriptive decoding error. JSONDecoder then happily produces [FeedItem], and call sites switch over the cases with full type safety.
Read the original → paul-samuels.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.