Showing posts with label cocoa. Show all posts
Showing posts with label cocoa. Show all posts

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. 

Friday, November 14, 2008

iPhone development for Rails and Web 2.0 developers

Interestingly, many of the new iPhone developers seem to come from a Rails / Web 2.0 background. I am one of those guys who did Rails projects and now is sitting in front of XCode doing iPhone development.

I really like developing in Rails and appreciate it's simplicity and elegance. So here I am, I went through the process of morphing from Ruby on Rails to Objective-C/Cocoa.

Are there any techniques and skills I could transfer from Rails to iPhone development?
  1. Model-View-Controller (MVC) pattern
    MVC is the key pattern in COCOA. So, great there is one thing you would understand already when playing around with iPhone development.
  2. Asynchronous UI on iPhone / AJAX on web 2.0
    AJAX-based web apps are great. If you have used AJAX and tried to understand the structure of how AJAX is used to make web 2.0 apps simple then you will be in a good position to make it "simple on the outside and complex on the inside". Cocoa on the iPhone can get information asynchronously from any web source. Check out NSURLRequest in asynchronous mode.
  3. Database on iPhone
    There is SQLite support on the iPhone. Great if you are planning to build a self-contained app that needs to manage some data locally on the iPhone. I have found that I have less need for a database on the iPhone. The way we build our iPhone applications are mostly using the User Preferences locally on the iPhone to persist any UI state. The heavy lifting in terms of Data Storage is done on Rails-based applications and I integrate both through RESTful APIs. If you need SQLite in your iPhone app then you might want to look into Schema Migration support for the SQLite library FMDB
  4. RESTful
    I like to keep the iPhone app lean and this is why I make good use of REST. The iPhone app is my REST client and our Rails applications offers the RESRful APIs. We integrate both through the RESTful APIs using a JSON framework for the iPhone. Actually, in some cases we use a simple POT (Plain Old Text) approach to transfer simple atomic text data from the Rails application and database to the iPhone front-end. This approach has proven as highly successful due to it's simplicity. (I hope I can find some time to post some receipes soon)
  5. Metaprogramming on the iPhone?
    If you have used Metaprogramming in Ruby before you will have some benefits when you work with Objective-C/COCOA but I haven't seen as much use of it. Objective-C does support dynamic typing and you can send any object any message and decide during runtime what to do with it. You will come across a method called respondsToSelector that can check whether an object can respond to a particular method call. I am just starting to realise what can be done in Objective-C in terms of Metaprogramming. Not a much as in Ruby but better than C++.
  6. Test-Driven-Development (TDD) or Behavior-Driven-Development (BDD):
    Sorry, not a lot of support on the iPhone for TDD or BDD. Unit testing and RSpec are not available. Considering how many Rails developers are also playing around with the iPhone SDK I am certain that there will be tools soon that will support TDD/BDD for the iPhone. So, how do you do proper testing? I will need to dedicate a separate blog entry to that topic. Stay tuned. (There are some tools that let you use Ruby to run test and migrations for iPhone code.)
  7. Delegation Pattern:
    I found the Delegation Pattern the most powerful pattern for iPhone development. Delegates are used everywhere in the Cocoa framework. I started to use it heavily to realise notifications between different controllers via protocols. Take some time to get comfortable with it. It will make things so much easier when you develop a more complex iPhone app. Check the Apple Developer Documentation. Check out this nicely written article abut the different ways of listening, observing and notifying in Cocoa
I hope I can find some time to post some of the architecture decisions we made along the way as we developed some pretty complex iPhone apps with various integration points.