Thoughts about Swift JSON Mapping libraries: better alternatives to ObjectMapper

Let me gather here the reasons why, in my opinion, there are better library than ObjectMapper.

The choice of the Mapping library impact the coding style/syntax.

Manual mapping, if done correctly, works great and is the a flexible solution. But I have to admit that it’s also verbose and error prone.

If smarter/verified tools have been made by other people than me, I should use them in order to increase productivity/safety.

First of all we can look at this graphic from a benchmark made by @Bwhiteley (github)

You can see that your choice can impact performances greatly. But performances are not the only thing we are looking for, syntax is important, also the fact that the library is widely used and will kept being supported in the futur.

The needs (tl;dr : Access safely and easily the JSON content / produce readable & maintainable code) :

  • Model and Mapping shouldn’t be coupled.
  • The model definition should reflect the actual requirements as close as possible, if the object is not consumable without its identifier then its identifier property shouldn’t be defined as optional.
  • Preferably having the mapping done during the object initialization.
  • Have the initializer being failable for better error handling.

The problems with ObjectMapper :

  • Mapping happens after object initialization (precisely the mapping() method), which means that all the properties are declared as mutable optionals.
  • If we want to remove optionals we have to provide default value (as in the Contributor class in the current code).
  • From what I saw most of the properties are optionals in the currently implemented model, but still.
  • Since all our properties are defined as optionals, mapping will succeed even if you feed the mapper an arbitrary piece of JSON data.
  • Because mapping cannot fail, ObjectMapper cannot report mapping errors like a missing key or a mismatch.
  • The consequence is that error handling is moved from the model layer to the layer that consume the model.
  • Performances (see the figure at the end of this mail)

The candidates (solving most of the problems aforementioned) :

Argo, by Thoughbot

  • Widely used
  • 2 dependancies (Runes and Curry). Increase app Startup time
  • Too much functional operators
  • The worst mapping performances (from @Bwhiteley bench, link below)

Decodable, by Anviking

  • Inspired by Argo but with a reduced number of functional operators

Marshal, by Utahiosmac (personnal preference)

  • As close as possible to vanilla swift syntax
  • Best performances (from @Bwhiteley bench, link below)
  • Fairly new library

Mapper, by Lyft

  • Good performances (from @Bwhiteley bench, link below)
  • Cleanest syntax
  • Fairly new library

Thanks for reading.

Research axes:

References :

EDIT: A new lib shared by Kevin Ballard on swift-lang may be the ultimate contender PMJSON