How to Use Java Script Object Notation in iOS Apps - dummies

How to Use Java Script Object Notation in iOS Apps

By Rajiv Ramnath

JavaScript Object Notation (JSON) has become the de facto standard in terms of representing data in iOS apps. You can use JSON to transfer data across the web and as the format for saving and retrieving long-lived data. JSON is both human-readable and easy for machines to understand. Data in JSON can be in one of two structures:

  • An object comprising an un-ordered set of name-value pairs. Each name-value corresponds to an attribute of the object. Each name-value pair can be nested, in case the attribute being represented is hierarchical in nature.

  • An ordered array of values. Each value in the array can be a scalar (a Boolean, string, or number value), an object, or an array.

In Tic-Tac-Toe, JSON represents the state of a game. This state consists of the following:

  • The current player (player 1 or player 2) is represented as an integer (0 for Player 1, and 1 for Player 2).

  • The state of the game — whether it’s active or complete; if it’s complete, whether it’s won or drawn; and if won, by whom.

    The states are also represented as integers, with Inactive being –1, Active being 0, Won being 1, and Draw being 2.

  • The state of the grid — that is, what symbols are present in each of the squares on the grid. Note that the symbols are represented as the integer values 0, 1, and 2, which stand for Blank, X, and O, respectively.

  • The current symbol (the one that will be played on the next move). Here (and just to vary the example), we represent the symbol as the string “X” or the string “O” or a blank (” “).

  • The play count (the number of moves made to the current point in the game) is represented as an integer.

In this code, we show the JSON object corresponding to an and active Tic-Tac-Toe Game:

image0.jpg

{
 "TTTGameKeyCurrentPlayer" : 0,
 "TTTGameKeyState" : 0,
 "TTTGameKeyGridState" : "2,1,2,2,1,0,1,2,1",
 "TTTGameKeyCurrentSymbol" : "X",
 "TTTGameKeyPlaycount" : 8
}

JSON easily maps to the available data structures (such as array, structures, and objects) in pretty much every programming language. The object form of JSON easily maps to programming language objects or structures, whereas the array form of JSON can map to an array, vector, list, or sequence, basically whatever data structure can hold an ordered collection of objects.

In Tic-Tac-Toe, the JSON object corresponding to the state of the game is mapped to a NSDictionary, because a NSDictionary object also consists of nested name value pairs. As a result, when you have to save the state of the game, you get its state as an NSDictionary object and then convert it to a JSON string.

When you retrieve the state of the game, you do the opposite — you read in JSON data and convert it to an NSDictionary object and then use the NSDictionary to restore the game to the saved state.

The following example shows this conversion from a dictionary object to JSON and from the JSON data object to a string (from the method saveGame in the Game Session view controller — files TTTGameSessionViewController.m and .h):

 - (IBAction) saveGame:(id)sender {
  NSDictionary* savedGameDictionary = [activeGame toDictionary];
  NSError *error;
  NSData *jsonData =
   [NSJSONSerialization dataWithJSONObject:savedGameDictionary
         options:NSJSONWritingPrettyPrinted
         error:&error];
  NSString *savedGameString =
   [[NSString alloc] initWithData:jsonData
   encoding:NSUTF8StringEncoding];
  NSString *savedGamesFilePath =
   [NSHomeDirectory()
    stringByAppendingPathComponent:@TTTGAMESESSIONSAVEDFILEPATH];
  [savedGameString writeToFile:savedGamesFilePath
          atomically:YES
          encoding:NSUTF8StringEncoding
          error:NULL];
 }

The important method here is in the method dataWithJSONObject from the NSJSONSerialization class.

You can see the reverse operation (that is, from a JSON string to an NSDictionary) in the restoreGame method in the same view controller:

- (IBAction) restoreGame:(id)sender {
  NSLog(@"Restoring game");
  …
  NSError *restoreError = nil;
  NSMutableDictionary *savedDictionary =
   [NSJSONSerialization JSONObjectWithData:[savedGameString
         dataUsingEncoding:NSUTF8StringEncoding]
         options:NSJSONReadingMutableContainers
         error:&restoreError ];
  activeGame = [[TTTGame alloc] initFromDictionary:savedDictionary];
  TTTGameGrid *gameGrid = [activeGame getGameGrid];
  if (![activeGame isActive])[boardView disableInput];
  [boardView setGrid:gameGrid];
  [gameView redraw];
 }

Here the key method is the JSONObjectWithData, which does the reverse operation of creating the Objective-C NSDictionary from JSON data.