Canappi's Data Binding Framwork allows you get data from a Web API and effortlessly bind it to your UI.
For instance, getting a Twitter feed and binding it to a table is as simple as that.
The core of the Canappi's binding framework relies on a simple assumption: Good Data is simple to bind. You shoudn't need a complex set of metadata,let alone a query language, to describe what you want to do. With Canappi, we reify data formats to a simple set of rows to keep the data binding definition (almost) always simple.
In XML, we often run into formats is something like that:
<collection>
<someOtherElement>...</someOtherElement>
<row attr1="value1" attr2="value2"> <key3>value3</value> ... </row>
<row>
...
</row>
</collection>
The data binding definition is generally achieved with a couple of values: the collection element (since it could be arbitrarily nested) and the row element.The algorithm can go arbitrarily deep to find them. Of course, we reify elements and attributes in a single dictionary for each row. In the case of the twitter feed we don't even specify the collection and the row elements since the feed is well formed and follows already the /collection/row format.
Things are a bit more complex with JSON. I found it a bit harder to identify where the "array" of rows is. Here is my reification algorithm. First, I identify where the rows are, then I flatten any subdictionary (and I ignore for the most part subarrays):
You know what? the life of the json data binder would be a lot simpler if API designers would also support a "mobile friendly" format. In JSON it could look like:
{
"collection": [
{
"row": {
"key1": "value1",
"key2": "value2"
...
}
},
{
"row": {
"key1": "value1",
"key2": "value2"
}
},
...
]
}
What's the point of arbitrarily nested data structures (in a mobile world) ?
So here is the implementation of our algorithm, you can dowload an adaptation of the SBJSONParser on Github.
This is how you use it:
url = [NSURL URLWithString:endpoint];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
request.requestMethod = @"GET" ;
[request startSynchronous];
NSString *response = [request responseString];
// Canappi tests for JSONP and removes it first
// See generated code
id data = nil;
SBJsonParser *parser = [[SBJsonParser alloc] init];
//Get a JSON object
id parsedData = [parser objectWithString:response error:nil] ;
//First find the array, then flatten the rows, to get an array or simple key/value pairs dictionaries
data = [parser flatten:[parser findArrayForElement:@"collection" andRow:@"row" wrapped:NO in:parsedData] forElement:nil] ;
Canappi also provides the ability to "join" two API calls and simply merge both set of rows in the same data structure.
This post is a plea for API designers: Please give mobile developers the data structures they need to simplify the data binding process. There is simply no value in doing otherwise, just incidental complexity.