Swift — Parse JSON like a boss

Sacha Durand Saint Omer
Yummypets Developers
3 min readNov 14, 2015

If you have an app, I can bet that it talks to the network. And if it does, chances are you’re using JSON. In this article we are going to see a straightforward approach that works and requires very little code.

Here is the link to the corresponding online Playground

Requirements

As always, its useful to start with requirements instead of rushing into the code.

What do we want?

  • Simple, Lightweight, Extensible, Easy to use
  • Leave our models clean
  • Implicitely cast JSON values to the right types declared in our models
  • No crash if JSON key is not there, nor returns nil, it simply shouldn’t do anything

Of course we do not want to add this information in our models because the models should NOT depend on the json parsing logic. The mapping should sit on top of models.

Let’s Code

Here we want to build a swift model out of a JSON representation.

With Swift, as usual, we start with a protocol.

And here is our Profile Model :

So let’s make it conform to the protocol :

Well, that works but it’s a lot of dummy code to write isn’t it ? Plus it’s not really easy to use. If we look carefully at our code, we see that we try to cast each json value to the type of the Model property. But the Type, for example Int for the identifier is already stored in our Property!

We can do better than that, so let’s be creative!

Let’s create a custom generic operator that does just that, aka testing the json value against the type of the property. Arrow is born!

Now our mapping looks like this \o/

Much better, more concise and readable ❤️

Bonus

Supporting Optionals

But this does not work for optionals does it? Indeed, as you might have noticed, our arrow operator wasn’t working with optional properties. In order to do so, we just need to provide the optional version for it which is the following :

That was easy wasn’t it ?

Nested Resources

And what about nested resources? For example what if my Profile model has Stats which is another Swift model ?

Let’s use a Fat Arrow to parse nested resources!

Add the mapping code for Stats :

And parsing a nested resource is now super straightforward !!!

Voila \o/

With this approach, we have a simple way to manage JSON to swift mapping. The parsing uses built-in swift casting capabilities to make sure JSON values are cast to the right Type. If the cast fails or the key is missing from the JSON, it fails gracefully and so without setting our model property to nil or some default value. On top of that, our curstom operator keeps our mapping logic concise and readable

Icing on the cake, our Model classes (structs!👍) stay clean and adding JSON mapping is as simple as adding a new extension “Model+JSON” ❤️.

Here is the link to the online Playground, have fun 🎉🎉🎉🎉

Arrow <- -

What we have just built is actually a small library that we use for parsing JSON.

It’s available via the great Dependency manager Carthage :

github "s4cha/Arrow"

Or checkout source code here: https://github.com/s4cha/Arrow

Happy Coding!

Special thanks to YannickDot for proofreading

--

--

Sacha Durand Saint Omer
Yummypets Developers

Avid learner, iOS Engineer @Yummypets, ❤ Swift, Health, Languages & Music