Tuesday, March 8, 2011

IPhone–json deserialization of custom objects

[Update – 27-Jan-2012, Starting with iOS5 you can use built-in NSJSONSerialization class,  example here: http://www.raywenderlich.com/5492/working-with-json-in-ios-5] 

After last entry on serialization I still owe a snippet for deserialization.
Since that time my class grew up a bit and now its json string read from db is:

{"environment":
  {"fixedLongitude":"14.471223","name":"mobile","fixedLatitude":"50.135194",
    "plans":[
        {"tasks":[{"title":"baby cries","dur":"10","durUnit":"2","desc":""}],
          "title":"babysitter!","description":""},      
        {"tasks":[{"title":"this is it","dur":"10","durUnit":"2","desc":""}],
          "title":"cook!","description":"Sample plan description"}]}}

And here is a snippet to reversing it back into the object (with jsonString value provided above):

    // Getting a json string from db
    NSString *jsonString = [[NSString alloc] initWithUTF8String: (char*) sqlite3_column_text (dbps, 0)];
    NSLog(@"data from db: %@", jsonString);
    // Top level dictionary, only contains "environment" key
    NSDictionary *dictionary = [jsonString JSONValue];
    // Retrieve "environment" itself
    NSDictionary *env = [dictionary objectForKey:@"environment"];
    // From "environment" dictionary get plans array as a "plans" key
    NSArray *plansArr = [env objectForKey:@"plans"];
    // For simple "environment" attributes retrieval is simple
    _environment.fixedLatitude = [[env objectForKey:@"fixedLatitude"] doubleValue];
    _environment.fixedLongitude = [[env objectForKey:@"fixedLongitude"] doubleValue];
    
    // Now getting to traverse the "plans" array, logic of traversal down the tree is same as above
    for (int i=0; i < [plansArr count]; i++) {
        NSDictionary *planJ = [plansArr objectAtIndex:i];
        Plan *p = [[Plan alloc] initWithTitle: [planJ objectForKey:@"title"] 
                                 description: [planJ objectForKey:@"description"]];
        
        NSArray *tasksJ = [planJ objectForKey:@"tasks"];
    
        for (int j=0; j < [tasksJ count]; j++) {
            NSDictionary *taskJ = [tasksJ objectAtIndex:j];

[p AddTaskWithTitle:[taskJ objectForKey:@"title"]
duration:[[taskJ objectForKey:@"dur"] intValue] unit: [[taskJ objectForKey:@"durUnit"] intValue]
link:[taskJ objectForKey:@"desc"]];

    }
        
        [[_environment plans] addObject:p];
        [p release];
    }
    
    
    [jsonString release];

This is it!

No comments: