Serialization in Swift

I wanted to add a description of a use case that must be incredibly common, but I found maddeningly difficult to address with 🐟able.

I have a data structure with many repetitions of a single value scattered throughout, and the value can be quite large (the contents of a source file). That's not a problem for my data structure, since variable-sized data in Swift is always CoW'd: copies are cheap. Obviously when I encode my data structure I don't want to end up with multiple copies in the archive, so they need to be deduplicated and serialized once. This deduplication pattern is commonly needed by people who serialize networks of class instances, which makes it not a little shocking to me that it's not already supported.

The changes I ended up with are here. They are quite awful… but they were the best I could do. I'm happy to answer any questions.

Particular obstacles:

  • deduplication requires communicating information gathered during the encoding of subparts of the data structure up to the process of encoding the part of the data structure that knows about the deduplication, but there only vehicle for that communication is the userInfo dictionary
  • Attaching mutable state to a userInfo dictionary is incredibly awkward, and can only be done to the top level encoder, which means you have to know about and accommodate this pattern at the top level of your whole data structure, and therefore your data structure can't be composed into other 🐟able data structures.
  • The encoders/decoders actually used by the encoding/decoding methods of a type are not the same as the top level encoders/decoders (e.g. JSONEncoder), which do not even conform to Encoder/Decoder

This problem is very similar to the one @Loooop is solving, but it applies even if there are no classes in play.

3 Likes