zw

How to use JSON in Cocoa/Objective-C

Using JSON in Cocoa is simple thanks to an excellent open-source JSON Framework by Stig Brautaset. The framework will decode a JSON string into native Objective-C objects, and vice versa . The project includes a packaged Framework, Mac and iPhone SDKs, as well as the source code. The easiest method is to directly embed the source in your app as it's pretty lightweight, and will work on both Mac and iPhone apps. Here are step-by-step instructions on how to use JSON in your app. (click the images to enlarge)

cocoa-json_step1 1.) Download the latest version (currently 2.2.1) from http://code.google.com/p/json-framework/downloads/list

cocoa-json_step2

2.) Open the dmg, and drag the JSON folder into your project in Xcode. Check "Copy items into destination group's folder (if needed)" when prompted.

3.) Once the source is embedded into your project, you need to import the framework to use it in your code

#import "JSON.h"

4.) Create a SBJSON object to parse JSON into a native Cocoa object. SBJSON will return either a NSDictionary or NSArray depending on the structure of the data. You should know ahead of time the structure of the JSON object your parsing and whether it's a single JSON object or an array of JSON objects and use the appropriate Cocoa class.

// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
  
// parse the JSON string into an object - assuming json_string is a NSString of JSON data
NSDictionary *object = [parser objectWithString:json_string error:nil];

Here's an example showing how to download the public timeline from Twitter as JSON and parse it.

// Create new SBJSON parser object
SBJSON *parser = [[SBJSON alloc] init];

// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://twitter.com/statuses/public_timeline.json"]];

// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];

// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
NSArray *statuses = [parser objectWithString:json_string error:nil];

// Each element in statuses is a single status
// represented as a NSDictionary
for (NSDictionary *status in statuses) {
  // You can retrieve individual values using objectForKey on the status NSDictionary
  // This will print the tweet and username to the console
  NSLog(@"%@ - %@", [status objectForKey:@"text"], [[status objectForKey:@"user"] objectForKey:@"screen_name"]);
}

Update (9/16/09): I just wrote a post about debugging API requests that might be helpful if you're having problems using this with another API - Debugging API requests with HTTP Client

Update (8/16/10): I wrote this article about a year and half ago, and everything in it still perfectly valid (except the version of json-framework which is now at 2.3), and a good approach to using JSON in Cocoa. However, I did want to mention that my current preferred method is to use yajl-objc. Yajl-objc is a set is Objective-C bindings for the C-based YAJL JSON library that works on both Mac OS and iOS. The main benefits of using YAJL, is that it's quite a bit faster since it's written in C. I won't reiterate here how to use yajl-objc as the instructions on the github page are pretty clear.