JSON Framework for iPhone (Part 2)
October 20, 2008
Editor’s Note: Due to the popularity of this iPhone JSON series, a new three part tutorial series on working with JSON was published in August 2009. You can find the latest JSON iPhone tutorial series at the links below:
In part 1 we shared with you how to download, install and configure an iPhone project to use a JSON framework developed by sbrautaset. In today’s post I will share with you how to use the framework to download and parse a JSON feed. As you will see it is much easier to deal with JSON within an iPhone application than to have to deal with XML.
JSON is most commonly used as an alternative to XML for RESTful style web services. As such any example that demonstrates anything about JSON must first begin with an example of how to download JSON data.
Let’s begin by creating a method called stringWithUrl: that will download data from a specified URL and return the data as an NSString
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | - (NSString *)stringWithUrl:(NSURL *)url { NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30]; // Fetch the JSON response NSData *urlData; NSURLResponse *response; NSError *error; // Make synchronous request urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; // Construct a String around the Data from the response return [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding]; } |
Now that we have the ability to download the JSON data as a string we are ready to parse the string into an object we can use. What is wonderful about this particular JSON framework is that it can parse JSON into a collection of NSDictionary and NSArray objects which are amazingly simple to deal with.
Combined with the stringWithUrl: method above, we are now ready to use the JSON framework to create another method that will parse the JSON string into an Object …
1 2 3 4 5 6 7 8 | - (id) objectWithUrl:(NSURL *)url { SBJSON *jsonParser = [SBJSON new]; NSString *jsonString = [self stringWithUrl:url]; // Parse the JSON into an Object return [jsonParser objectWithString:jsonString error:NULL]; } |
NOTE: The method above returns id because the actual object type can vary between an NSDictionary and an NSArray.
Now let’s put this to use! First, consider a real example of a JSON feed. Here is a sample of what a public feed from Jaiku looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | { "title" : "Jaiku | Latest Public Jaikus", "url": "http:\/\/jaiku.com", "stream": [ { "id": "47163562", "title": "Lol....nope", "content": "", "icon": "http:\/\/jaiku.com\/images\/icons\/jaiku-sms.gif", "url": "http:\/\/vicious00013.jaiku.com\/presence\/47163562", "created_at": "2008-10-20T18:22:50 GMT", "created_at_relative": "1 minute ago", "comments": "0", "user": { "avatar": "http:\/\/jaiku.com\/image\/4\/avatar_52304_t.jpg", "first_name": "Ronnie", "last_name": "Beckett", "nick": "vicious00013", "url": "http:\/\/vicious00013.jaiku.com" } }, { "id": "47163407", "title": "Nice, so HP refuses to (or can't) sell us the drive carriers for their servers.", "content": "", "icon": "", "url": "http:\/\/randomfrequency.jaiku.com\/presence\/47163407", "created_at": "2008-10-20T18:21:16 GMT", "created_at_relative": "3 minutes ago", "comments": "3", "user": { "avatar": "http:\/\/jaiku.com\/image\/36\/avatar_47586_t.jpg", "first_name": "Vincent", "last_name": "Janelle", "nick": "randomfrequency", "url": "http:\/\/randomfrequency.jaiku.com" } } ] } |
Here is an how we would use the above methods to download the public feed from Jaiku and cast it to an NSDictionary …
1 2 3 4 5 6 7 | - (NSDictionary *) downloadPublicJaikuFeed { id response = [self objectWithUrl:[NSURL URLWithString:@"http://jaiku.com/feed/json"]]; NSDictionary *feed = (NSDictionary *)response; return feed; } |
At this point we have everything we need to query any aspect of the feed. For example here is how you might query the “title” field:
1 2 | NSDictionary *feed = [self downloadPublicJaikuFeed]; NSLog(@"Here is the title of the feed: %@", [feed valueForKey:@"title"]); |
Notice in the sample Jaiku feed there is a value “stream” that is actually a list of objects. This is an example of how an NSArray is created to contain a list of object in JSON. Although the JSON frameworks creates the array, you will still need to cast it from a generic ‘id’ type into an NSArray before you can use it safely. Here is an example of how we would query the array of objects and handle each object in the array…
1 2 3 4 5 6 7 8 9 10 11 12 | NSDictionary *feed = [self downloadPublicJaikuFeed]; // get the array of "stream" from the feed and cast to NSArray NSArray *streams = (NSArray *)[feed valueForKey:@"stream"]; // loop over all the stream objects and print their titles int ndx; NSDictionary *stream; for (ndx = 0; ndx < stream.count; ndx++) { NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:ndx]; NSLog(@"This is the title of a stream: %@", [stream valueForKey:@"title"]); } |
Conclusions
As you can see, working with JSON feeds are much simpler than XML feeds. There is no cumbersome parser you have to create; and getting values from the JSON object is as simple as working with an NSDictionary or NSArray. If only more Web Service APIs used JSON the world would be a better place!



