I have been using the Jackson library in Java for automatic serialization to and from JSON to native objects. Recently I had to implement something similar in the iPhone SDK. I had to google around as the tool chain is not as developed as it is for Java. The best library I have been able to find is JSONKit. This is a short tutorial detailing how to get it working.

First download the JSONKit.h and JSONKit.m files and add them to your project source.

Then create an xCode project for your code to go in if you don’t already have one. I am going to use my project from the Hello World tutorial which you can download from github.

Now import the file into your source files wherever you would like to parse to and from JSON source which in may case that is HelloWorldViewController.m

#import JSONKit.h

 

Creating our Json Strings

Before we start writing out awesome parsing code lets make some JSON string that we wish to parse. I use a tool called JSONLint to create JSON snippets for testing. Here are some test snippets I came up with.

  • Single Parameter
  • {
        "person": "Usman"
    }

     

  • Nested Parameters
  • {
        "person": {
            "name": "Usman",
            "job": "Software Engineer"
        }
    }

     

  • Nested Parameters
  • {
        "directory": [
            {
                "person": {
                    "name": "Usman",
                    "job": "Software Engineer"
                }
            },
            {
                "person": {
                    "name": "Someone else",
                    "job": "Some other profession"
                }
            }
        ]
    }

     

    Next we create three methods to return the JSON strings in the form of NSData objects in HelloWorldViewController.m, I have hard coded the strings as shown above with proper escaped characters for line endings and quotation marks.

    - (NSData*) getSimpleJSON {
        NSString* jsonString = @"{\"person\": \"Usman\"}";
        return  [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    }

     

    - (NSData*) getNestedJSON {
        NSString* jsonString = @"{                      \
            \"person\": {                               \
                \"name\": \"Usman\",                    \
                \"job\": \"Software Engineer\"   		\
            }                                           \
        }";
    
       return  [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    
    }

     

    - (NSData*) getJSONList {
        NSString* jsonString = @"                                \
        {                                                       \
            \"directory\": [                                    \
    			{                                           	\
    				\"person\": {                             	\
    					\"name\": \"Usman\",                  	\
    					\"job\": \"Software Engineer\"        	\
    				}                                         	\
    				},                                         	\
    				{                                           \
    					\"person\": {                           \
    						\"name\": \"Someone else\",         \
    						\"job\": \"Some other profession\"  \
    					}                                       \
    				}                                           \
    		]                                                   \
        }";
       return  [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    
    }

     

    Parsing JSON

    Look for the -(void)action:(id)sender method in the code and delete all the code within the method. In it’s place we will first initialize an instance of the JsonDecoder. We then use the objectWithData of the decoder to parse our simple JSON String into a NSDictionary object. Each property in the json source becomes a key value in the dictionary. The code below shows how we would retrieve the the value of a particular property and output it to console log.

    -(void)action:(id)sender {
        JSONDecoder* decoder = [[JSONDecoder alloc] init];
        NSDictionary *resultsDictionary = [decoder objectWithData:[self getSimpleJSON]];
        NSLog(@"Person: %@",[resultsDictionary objectForKey:@"person"]);
    }

     

    Each nested object is parsed as a dictionary of its own, for example when we parse the nested json string we first get a dictionary which contains a key mapping from person to another dictionary. The second dictionary contains the person’s name and job as key value pairs as shown in the code below.

        NSDictionary *nestedDictionary  = [decoder objectWithData:[self getNestedJSON]];
        NSDictionary *personDictionay =  [nestedDictionary objectForKey:@"person"];
    
        NSLog(@"Name: %@",[personDictionay objectForKey:@"name"]);
        NSLog(@"Job: %@",[personDictionay objectForKey:@"job"]);

     

    JSON Lists map to a an NSArray object where each element of the list is mapped to a NSDictionary object containing the element. For example in our JSONList string the primary dictionary contains a key directory which maps to a NSArray of dictionaries. Each element in the NSArray maps to a NSDictionary with a key person which returns a dictionary with the name and job of the person.

    	
    NSDictionary* listDictionary = [decoder objectWithData:[self getJSONList]];
    NSArray* people =[listDictionary objectForKey:@"directory"];
    
    for (NSDictionary *person in people) {    
    	NSDictionary *personDetails = [person objectForKey:@"person"];
    	NSLog(@"Name: %@",[personDetails objectForKey:@"name"]);
    	NSLog(@"Job: %@",[personDetails objectForKey:@"job"]);
    }

     

    Running the code

    The complete method should now look something like the code shown below. Build & Run your project and click the button on the iPhone emulator when it pops up.

    	
    -(void)action:(id)sender
    {
        JSONDecoder* decoder = [[JSONDecoder alloc] init];
        NSDictionary *simpleDictionary = [decoder objectWithData:[self getSimpleJSON]];
        NSLog(@"Person: %@",[simpleDictionary objectForKey:@"person"]);
    
        NSDictionary *nestedDictionary  = [decoder objectWithData:[self getNestedJSON]];
        NSDictionary *personDictionay =  [nestedDictionary objectForKey:@"person"];
    
        NSLog(@"Name: %@",[personDictionay objectForKey:@"name"]);
        NSLog(@"Job: %@",[personDictionay objectForKey:@"job"]);
    
        NSDictionary* listDictionary = [decoder objectWithData:[self getJSONList]];
        NSArray* people =[listDictionary objectForKey:@"directory"];
    
        for (NSDictionary *person in people) {    
            NSDictionary *personDetails = [person objectForKey:@"person"];
            NSLog(@"Name: %@",[personDetails objectForKey:@"name"]);
            NSLog(@"Job: %@",[personDetails objectForKey:@"job"]);
        }
    }

     

    Look at your console log and it should show the parsed out data that we printed to the log:

    	
    2011-10-16 17:45:12.201 HelloWorld[4005:f803] Person: Usman
    2011-10-16 17:45:12.203 HelloWorld[4005:f803] Name: Usman
    2011-10-16 17:45:12.203 HelloWorld[4005:f803] Job: Software Engineer
    2011-10-16 17:45:12.204 HelloWorld[4005:f803] Name: Usman
    2011-10-16 17:45:12.204 HelloWorld[4005:f803] Job: Software Engineer
    2011-10-16 17:45:12.204 HelloWorld[4005:f803] Name: Someone else
    2011-10-16 17:45:12.205 HelloWorld[4005:f803] Job: Some other profession

     

    Source Code

    The updated HelloWorld project source code with changes that we made in this tutorial can be downloaded at github.