Json – How to map JSON objects to Objective C classes

deserializationjsonobjective-cserialization

I'm mapping JSON-formatted data from a web server to Objective C classes (NSManagedObjects modeled in Xcode, handled by Core Data). For each attribute of the Objective C class, I need to:

  1. Determine if the attribute's key exists in the JSON object,
  2. Determine if the value for that key is not null, and
  3. Pass the value to the modeled class instance if conditions 1 and 2 are true

Right now, I'm hard-coding this sequence for each of the attributes, so every attribute needs code like the following:

// dictObject is the JSON object converted into a NSDictionary,
// and person is the instance of the modeled class

if ([dictObject objectForKey:@"nameFirst"] &&
    [dictObject objectForKey:@"nameFirst"] != [NSNull null]) {
    person.nameFirst = [dictObject objectForKey:@"nameFirst"];
}

Besides requiring a lot of code to handle the various classes, this seems kludgy and brittle: any name change (or language localization) would cause the mapping to fail.

There has to be a better way… what am I missing?

Best Solution

For handling the NULL values, make use of a category on NSDictionary. I use a category that looks like this:

NSDictionary+Utility.h

#import <Foundation/Foundation.h>


@interface NSDictionary (Utility) 
- (id)objectForKeyNotNull:(id)key;
@end

NSDictionary+Utility.m

#import "NSDictionary+Utility.h"


@implementation NSDictionary (Utility)

- (id)objectForKeyNotNull:(NSString *)key {
   id object = [self objectForKey:key];
   if ((NSNull *)object == [NSNull null] || (CFNullRef)object == kCFNull)
      return nil;

   return object;
}

@end

Retrieve any values from your JSON dictionary like this:

NSString *stringObject = [jsonDictionary objectForKeyNotNull:@"SomeString"];
NSArray *arrayObject = [jsonDictionary objectForKeyNotNull:@"SomeArray"];