Deserialize JSON To Objective-C Objects – iOS And JSON Part 2

December 12, 2013

In Part 1 of the series Serialize Objective-C Objects to JSON I wrote a few examples for serializing objects into JSON. Specifically, a dictionary with several key/value pairs as well as an array. In this post I will show the opposite, how to deserialize JSON to Objective-C objects.

It’s important to note that the examples in both of these posts use the NSJSONSerialization class that Apple released beginning with iOS 5. For basic JSON serializing and deserializing no external library is required.

To keep the code focused on the task at hand, rather than include a bunch of networking code to acquire JSON, I will simulate the process and simply read JSON from a file that I’ve added to my project. The file contents are extracted from a Twitter API example that lists JSON for a sample search:

The JSON from the Twitter search follows:

{
  "completed_in": 0.012,
  "max_id": 136536013832069120,
  "max_id_str": "136536013832069120",
  "next_page": "?page=2&max_id=136536013832069120&q=twitterapi&rpp=1",
  "page": 1,
  "query": "twitterapi",
  "refresh_url": "?since_id=136536013832069120&q=twitterapi",
  "results": [
    {
      "created_at": "Tue, 15 Nov 2011 20:08:17 +0000",
      "from_user": "fakekurrik",
      "from_user_id": 370773112,
      "from_user_id_str": "370773112",
      "from_user_name": "fakekurrik",
      "geo": null,
      "id": 136536013832069120,
      "id_str": "136536013832069120",
      "iso_language_code": "en",
      "metadata": {
        "result_type": "recent"
      },
      "profile_image_url": "http://a1.twimg.com/profile_images/1540298033/phatkicks_normal.jpg",
      "source": "<a href="http://twitter.com/">web</a>",
      "text": "@twitterapi, keep on keeping it real",
      "to_user": "twitterapi",
      "to_user_id": 6253282,
      "to_user_id_str": "6253282",
      "to_user_name": "Twitter API"
    }
  ],
  "results_per_page": 1,
  "since_id": 0,
  "since_id_str": "0"
}

Below I will describe how to deserialize the JSON above as well as demonstrate how to extract a few key/value pairs.

Deserialize JSON

The code example to deserialize JSON into objects follows. I’ll explain more about how things work after the code:

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
// Read JSON from a file (simulate internet download)
NSString *path = [[NSBundle mainBundle] pathForResource:@"json" ofType:@"txt"];
NSData *jsonData = [NSData dataWithContentsOfFile:path];
 
NSError *error = nil;
 
// Get JSON data into a Foundation object
id object = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&error];
 
// Verify object retrieved is dictionary
  if ([object isKindOfClass:[NSDictionary class]] && error == nil)
{
  NSLog(@"dictionary: %@", object);
 
  // Get the value (string) for key 'next_page'
  NSString *str;
  str = [object objectForKey:@"next_page"];
  NSLog(@"next_page: %@", str);
 
  // Get the value (an array) for key 'results'
  NSArray *array;
  // Get the 'results' array
  if ([[object objectForKey:@"results"] isKindOfClass:[NSArray class]])
  {
    array = [object objectForKey:@"results"];
    NSLog(@"results array: %@", array);
  }
}

Lines 2-3 simulate a network download of JSON. The JSON show at the top of the post is stored in the file json.txt, which is read into an NSData object.

The code to deserialize is shown on line 8 – the JSON stored as NSData is the first parameter, there are several options for how the data is treated and the final parameter will contain an NSError object if something goes amiss.

The dictionary output for NSLog on line 13:

dictionary: {
    "completed_in" = "0.012";
    "max_id" = 136536013832069120;
    "max_id_str" = 136536013832069120;
    "next_page" = "?page=2&max_id=136536013832069120&q=twitterapi&rpp=1";
    page = 1;
    query = twitterapi;
    "refresh_url" = "?since_id=136536013832069120&q=twitterapi";
    results =     (
                {
            "created_at" = "Tue, 15 Nov 2011 20:08:17 +0000";
            "from_user" = fakekurrik;
            "from_user_id" = 370773112;
            "from_user_id_str" = 370773112;
            "from_user_name" = fakekurrik;
            geo = "<null>";
            id = 136536013832069120;
            "id_str" = 136536013832069120;
            "iso_language_code" = en;
            metadata =             {
                "result_type" = recent;
            };
            "profile_image_url" = "http://a1.twimg.com/profile_images/1540298033/phatkicks_normal.jpg";
            source = "&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;";
            text = "@twitterapi, keep on keeping it real";
            "to_user" = twitterapi;
            "to_user_id" = 6253282;
            "to_user_id_str" = 6253282;
            "to_user_name" = "Twitter API";
        }
    );
    "results_per_page" = 1;
    "since_id" = 0;
    "since_id_str" = 0;
}

The code on lines 16-18 show how to extract from the JSON the string for the key ‘next_page’ using objectForKey to get the value from the dictionary.

The output for ‘next_page’ is below:

next_page: ?page=2&max_id=136536013832069120&q=twitterapi&rpp=1

The final object retrieved from the JSON is an array, the relevant code is on lines 21-26. First a check is made to verify that the object for the key ‘results’ is an NSArray. From there, simply read the array and display the data. The output for ‘results’ array follows:

results array: (
        {
        "created_at" = "Tue, 15 Nov 2011 20:08:17 +0000";
        "from_user" = fakekurrik;
        "from_user_id" = 370773112;
        "from_user_id_str" = 370773112;
        "from_user_name" = fakekurrik;
        geo = "<null>";
        id = 136536013832069120;
        "id_str" = 136536013832069120;
        "iso_language_code" = en;
        metadata =         {
            "result_type" = recent;
        };
        "profile_image_url" = "http://a1.twimg.com/profile_images/1540298033/phatkicks_normal.jpg";
        source = "&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;";
        text = "@twitterapi, keep on keeping it real";
        "to_user" = twitterapi;
        "to_user_id" = 6253282;
        "to_user_id_str" = 6253282;
        "to_user_name" = "Twitter API";
    }

As you can see, serializing and deserializing with JSON is quite straightforward with Apple’s NSJSONSerialization class.