iPhone SDK: Parsing JSON data

So when developing for the iPhone with the official SDK, and trying to parse JSON data, there are a few options for JSON libraries to use:

  • json-framework – General purpose JSON library for Objective-C, but contains a custom SDK that was built to be easily bundled with iPhone app projects.
  • TouchJSON – Part of the TouchCode, a project of a bunch of classes that are targetted for iPhone development, so it’s deemed to be a very light and fast library.
  • Maybe more? Let me know in the comments area.

Both are very under-documented (I mean, SERIOUSLY), but if you poke at them long enough, things will start making sense. I personally chose to use json-framework, as I initially had a few problems figuring out how to parse JSON content that had an array as the root object. Apparently TouchJSON officially only supports JSON results serialized as a object in the root level. As in:

{"values": ["value1", "value2", "value3"]}

Instead of:

["value1", "value2", "value3"]

That’s usually not a big deal, as you can just change the way you generate the JSON result in your server side code (if you are dealing with web services returning the JSON data), but what happens if you already have code expecting the server side to return that type of result?

Either way, I’m going to provide a simple usage example of json-framework to parse a JSON string. In order to install json-framework, you should follow the simple instructions available in its INSTALL file.

NSString *jsonString = @"[\"value1\", \"value2\", \"value3\"]";
SBJSON *json = [[SBJSON alloc] init];
NSError *error = nil;
NSArray *results = [json objectWithString:jsonString error:&error];
[json release];

For my particular application, I was fetching the JSON string from a web service, and it was coming up as a NSData object, so I had to do the following:

NSString *jsonString = [[NSString alloc] initWithData:resourceData encoding:NSUTF8StringEncoding];
SBJSON *json = [[SBJSON alloc] init];
NSError *error = nil;
NSArray *results = [json objectWithString:jsonString error:&error];
[json release];
[jsonString release];

Hopefully this is useful to someone else.

12 Comments »

  1. Mathieu said,

    December 30, 2008 @ 8:34 am

    Hello,

    I read you message on: http://stackoverflow.com/questions/288412/deserializing-a-complex-json-result-array-of-dictionaries-with-touchjson
    I need to parse the following JSON response: http://pastie.org/348983 and especially get the “name” parameter. I tried with TouchJSON and with the JSON-Framework you’re talking about, and it seems I cannot parse the inside of the “locations” part.

    Can you help me? There’s not good example or documentation on the web for that.

    Thank you so much for your help!

  2. Mathieu said,

    December 30, 2008 @ 10:43 am

    I don’t see the comment I submitted earlier today. Maybe I missed a confirmation step?

  3. jpm said,

    December 30, 2008 @ 11:12 am

    Mathieu,

    Sorry, your comment was still set to be approved.

    It’s actually pretty simple to decode JSON output, once you get the hang of it. You are totally right that it is very difficult to find documentation for any of this, which is why I wanted to write this post.

    In any case, since your JSON string has a dictionary as the outermost object, you need to tweak my original code sample a bit to make it work.

    // jsonString contains the actual JSON output from your web service
    SBJSON *json = [[SBJSON alloc] init];
    NSError *error = nil;
    // object containing full results
    NSDictionary *results = [json objectWithString:jsonString error:&error];
    // array just for the "location" results
    NSArray *locations = [results objectForKey:@"locations"];
    // first location in your array
    NSDictionary *firstLocation = [locations objectAtIndex:0];
    // finally, the name key
    NSString *name = [firstLocation objectForKey:@"name"];
    [json release];

    That should work just fine (not tested though).

    –Joao

  4. Mathieu said,

    December 30, 2008 @ 7:38 pm

    Joao,

    Thank you so much. It is working perfectly now. And I can just keep using TouchJSON only.

    Thanks!

  5. Matt said,

    January 7, 2009 @ 8:12 pm

    Can you help guide me on how to retrieve the data from a URL?

    Thanks!

  6. Rajendra said,

    January 9, 2009 @ 1:33 am

    I had write the same code in my application but it shown me data in markup tag i.e. means >, etc…

    Please give me response if you have any solution for the same….

    Thanks in advance.

  7. Gerald said,

    March 10, 2009 @ 9:03 pm

    Thanks for listing TouchJSON… Previously I was using BSJSON (as linked from json.org), but Touch is much much faster!

  8. Bahar said,

    June 11, 2009 @ 12:58 am

    I have developed a web service, which outputs JSON. So far I was using json-framework in fetching the web service in iphone. TouchJSON is much faster.

    Thanks for sharing it.

  9. Andre Tozzini said,

    December 10, 2009 @ 2:05 pm

    Hi Joao,

    Are you from Brazil or Portugal??? If so, we can speak in Portuguese maybe???

    Well, i need to parse a json response from http://geocoding.cloudmade.com/144de75073a54825818c7ffada69dadd/geocoding/v2/find.js?object_type=hospital&around=51.51384,-0.10952&distance=2000 for example but i really don’t know how to do it. What is better to use??? I need to get the coordinates from all hospitals near my gps position.

    Well that it…

    Thanx a lot

    Best Regards

    Andre Tozzini

  10. Ondrej said,

    December 17, 2009 @ 4:38 am

    Matt: I am using categories (that’s something that extends the main class u are using, in this case NSString)

    .h file:

    //
    // NSString+URL.h
    // urlTools
    //
    // Created by Ondrej Rafaj on 19.10.09.
    // Copyright 2009 Home. All rights reserved.
    //

    @interface NSString (urlTools)

    + (NSString *)stringWithUrlInUtf8:(NSString *)targetUrl;

    @end

    .m file:

    //
    // NSString+URL.m
    // urlTools
    //
    // Created by Ondrej Rafaj on 19.10.09.
    // Copyright 2009 Home. All rights reserved.
    //

    #import “NSString+URL.h”

    @implementation NSString (urlTools)

    + (NSString *)stringWithUrlInUtf8:(NSString *)targetUrl {
    NSLog(@”URL in String: %@”, targetUrl);
    NSURL *location = [NSURL URLWithString:targetUrl];
    NSError *error = nil;
    NSString *content = [NSString stringWithContentsOfURL:location encoding:NSUTF8StringEncoding error:&error];
    if (error) NSLog(@”Something went wrong %d, %@”, [error code], [error localizedDescription]);
    return content;
    }

    @end

    u have to import the file into the project and than just use:

    NSString *data = [NSString stringWithUrlInUtf8:@”http://www.example.com/your-json-file.json”];

    And that’s it :)

    I wrote a full tutorial about parsing JSON yesterday:

    http://www.xprogress.com/post-44-how-to-parse-json-files-on-iphone-in-objective-c-into-nsarray-and-nsdictionary/

    Cheers,

    Ondrej :)

  11. Eric said,

    February 4, 2010 @ 11:38 pm

    Joao.
    Thanks for the documentation. This helped me in a recent project! Hooray for JSON.

  12. Srikanth said,

    June 30, 2010 @ 3:01 am

    thanks for the answer to Mathieu’s question..I was having the same problem parsing complex JSON structures..thanks!!

RSS feed for comments on this post · TrackBack URI

Leave a Comment