As a mobile developer, I routinely work with JSON from APIs. Going from a JSON dictionary to a model object is something I do for just about every screen I build. On Android, I use a wonderful library called Gson which (more or less) automatically take JSON and populates a model object with the data. It’s magical to just say:
SomeModel model = new Gson().fromJson(json, SomeModel.class)
and be done!
For iOS, and specifically Swift, it’s another story. There are a few ways you can accomplish this:
- Manually map the JSON keys/values to properties.
- Use a library like ObjectMapper or Argo.
In either case you have to do something I find unpleasant: explicitly say which properties to map to which json keys.
For the vast majority of my own personal use cases, that’s pretty redundant. Most of the time, the properties I’m dealing with are llama case versions of the snake case JSON keys from the server. Most of the time, I don’t have to deal with performance issues. Most of the time, my objects are subclasses of
For cases like these, enter Eson.
To be clear, the circumstances described are not 100% of cases. But for those times that I don’t need something specialized, I don’t want to sacrifice usability for a bunch of features I’m not going to need. And it’s those times that I reach for Eson.
What makes Eson special? It handles the majority of cases for you, but lets you make changes if you want to. Most of the Rails or Node APIs I see around use snake case, and the iOS objects I create use llama case, so Eson’s default is to convert snake case json keys to llama case properties. If your server uses llama case (as many Node APIs do), simply pass Eson a boolean saying not to convert. Or, if you have different names on the server altogether, pass in a dictionary to explicitly map only those keys.
Eson uses reflection to populate properties. The advantage of this is it can auto detect your object’s properties so you don’t have to manually name them. This reduces your model’s size in lines of code, especially for models with a bunch of properties. It also means that just about any NSObject can be deserialized, even ones for which you don’t control the source code.
Eson autodetects the type of the property, and will try to create an object of that type out of the dictionary for that key. This means that most of the time when you have NSObjects with other NSObjects as properties, Eson will be able to traverse down that tree and instantiate all of them without any interaction from you.
Eson isn’t perfect, and there are a few gotchas. Obviously, having to subclass an
NSObject is one of them. This is because Swift 3.2/4.0 objects do not have robust reflection of their own yet (you can read properties but you can’t write them, basically). Hopefully in the near future this will change.
NSObject and the lack of robust reflection, there are some weird limitations. Any property that isn’t representable in Objective-C won’t be deserialized. Examples would include
Bool?. These properties can still be represented as
NSNumber?s, though, or you can make them simple
Bools with default values. You may also need to deserialize NSArrays separately, since they don’t always declare what type is in the array.
As always, examine your use case
Eson regularly saves me a bunch of code, and allows me to build apps that interact with APIs faster than ever. But as with everything, you should make sure it fits your use case. A good place to start is to check out the tests in the example project on Github, so go! Check it out and start saving time today!