Sunday, November 23, 2008

JSON and RESTful web services on the iPhone

We use JSON on the iPhone to access RESTful services on the Internet.

JSON seems to be the dominant and easiest way to use web services over the Internet. 
We used it in our native iPhone app (PinPoint) to integrate with Googles Geo Location APIs. Fortunately, Google supports JSON and XML. I have chosen to use JSON over XML for no particular reason other then "want to play".
 
What kind of app do you have?
  1. A web-based  app that runs on Safari
  2. A native iPhone app that uses Objective-C and Cocoa.
Both flavours of JSON-iPhone integration are covered in this blog entry.

1. A web-based  app that runs on Safari
JSON form web apps based on WebKit / Dashcode

The first iPhone JSON integration I did was for a web app that I developed with Dashcode. The app required only the list of trips from our Rails app. No associations or nested objects were required. The JSON response was an array of simple objects. This list was displayed as a typical table view and tapping an item opened the detailed view without making another http request. 
This exercise was surprisingly simple because I could deal with well-known technology (JavaScript, HTMP, CSS, DOM, AJAX).


2. A native iPhone app that uses Objective-C and Cocoa.
JSON using Objective-C / Cocoa / XCode

I have to admit this is not as nice as for the web app using WebKit/Javascript. Not really a surprise since JSON is actually a serialiseed JavaScript object and no mapping is required.

Using JSON in Objective-C / Cocoa is less natural. The Objective-C / JSON framework I used does return the JSON structure mainly as a NSDictionary and NSArray.

If you are using the JSON framework with the iPhone SDK 2.2 then check out this article.

I used JSON to get Geocoding data from Google. The Google JSON API was actually not documented at the time I developed my app, which made it a bit more exciting. The JSON structure that is returned by Google is a mix of nested objects and arrays. I would say that the Google Geo location API returns a pretty complex but well structured data structure.

The JSON framework  for Objective-C does all the hard work of mapping the JSON structure into Cocoa data structures (NSDictionary and NSArray). Now that the data is in Objective-C object my code needed to access the parts I am interested in. The code needs to be aware of the returned JSON structure and that is where I feel things become a bit hardcoded. I needed to access parts of the NSDictionary objects that where pretty nested and had to traverse the tree through pretty long statements.

Show me the code:
Here is a simple example that shows how I get the JSON data for a reverse geo coding call to Google. The exampled will get the address string from the JSON structure.

NSString *jsonRep    = [[NSString alloc]        
      initWithData:data 
encoding:NSUTF8StringEncoding];  
NSLog(@"Got this form JSON");
NSLog(jsonRep);
NSDictionary *dir = [jsonRep JSONValue];
NSArray *arrPlacemarks = [dir valueForKey:@"Placemark"];
NSDictionary *dirPlacemark0 = [arrPlacemarks objectAtIndex:0];
NSString *address = [dirPlacemark0 valueForKey:@"address"];
NSLog(address);

The code to get the more granular part out of the Geo location  JSON string is not that simple but in principle the same approach.  
1. You need to know where the particulare information resided in the JSON strucutre.
2. Navigate the structure to the particular NSDirectory or NSArray and get it.

What could break:
As soon as Google changes their API I am sure my app will break. The above approach will not survive any serious schema changes. As soon as Google changes the nesting of objets in their JSON response I will need to modify my code. 

1 comment:

Vinz said...

Great Article :-) Yeah JSON is a good thing on iPhone ! We made en similar article about json and iPhone where we give an example how to handle parsing error (here in french (sorry for english reader, but in the end it's code ^^). Have a good week :-)