So the single most common thing I run into, which is a source of all sorts of headaches when writing custom software for clients, is hooking into their back end system.
A very common pattern for me is to create a single interface which can perform a HTTP ‘get’ or ‘post’ call in order to obtain the contents, run everything through a JSON parser, and then handing the resulting NSDictionary or NSArray to an object which converts the results into a set of Objective C classes.
Up until now I’ve been using JSON Accelerator, which is a really nice little tool for converting JSON into a set of classes. But this runs into a couple of problems.
(1) A number of sites I integrate with have multiple JSON endpoints, each which return subtly different JSON results. Using JSON Accelerator and I wind up generating a lot of duplicate classes which represent more or less the same thing.
(2) Often those sites will change; after all, the back end is under development as well as the front end. I often have a hard time seeing the structure from the JSON; sometimes buried in a few hundred lines is a field that contains a null pointer or which was changed from a string to a JSON field–and tracking those bugs down can be a pain in the ass.
It seemed to me the best way to handle this is to have an intermediate representational language which allows me to see what it is that I’m working with, and to allow allow me to ‘tweak’ the results, so I can point out that the ‘Person’ record in call A is the exact same thing as the ‘Person’ record in call B, except for one of the fields being omitted.
So I built a simple analysis app and a simple compiler app to resolve this problem.
You can download the compiled tools and read the documentation (such as it is) from here.
The representational language is fairly simple: a set of objects, which can be compiled into Objective C and (when I have time) into Java. Each field in an object can be a primitive, an object or an array of objects. So, for example:
/* Feed * * Top level of the feed */ Feed { id: integer, name: string, date: string, active: boolean, addressList: arrayof Address, phoneList: arrayof Phone, } /* Address * * The user's address */ Address { id: integer, name: string, address: string, address2: (optional) string, // optional in the data stream city: string, state: string, zip: string } /* Phone * * The user's phone */ Phone { id: integer, name: string, phone: string }
Note that fields can also be marked as ‘nullable’:
Feed { id: integer, name: string, value: (nullable) real }
This will translate into an NSNumber * field rather than into a double.
There are also a couple of tools: one that generates the Objective C code, and one which reads in a bunch of JSON (in fact, it will read multiple JSON objects all in a row), and makes a best guess at the underlying structure, collapsing common objects as needed, and even noting when the same field appears to contain ambiguous content.
At some point I will need to clean this up, add Java support, and push this out to GIT. But for now, there you go.
Let me know if this seems useful.
Uploaded a new release which fixes a problem with the analysis tool changing the name of the JSON field. Updated the .jl syntax to allow arbitrary strings to be used as the field name; the back end will convert to a unique field which is similar to the field if needed.
LikeLike