Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object Mapping library from JSON to NSObjects

I am trying to build a parser/objectMapper that will build Objective C objects for the JSON I consume from a REST service.

I took some inspiration from RestKit by having my Entities all hold a "decoding list" which tells a mapper which JSON keys goes with which objects. Like this:

//ObjectEntity implementation
+ (NSDictionary*) mapProperties {

    /*
     localPropertiy - JSONProperty
     */

    return @{
            @"name": @"name", 
            @"category": @"category", 
            @"possible_scopes": @"possibleScopes",
            @"possible_descriptions": @"possibleDescriptions",
            @"key": @"keys"            
     };

}

+ (NSDictionary*) mapRelations {

    return [NSDictionary dictionary];
}

I did so because I like the encapsulation of these changeable values to be in the object that they reference. Making the Mapper know as little as possible.

The mapper does something like this:

+ (NSArray*) parseData:(NSData*) jsonData intoObjectsOfType:(Class) objectClass {

    //Parser result from web service
    NSError *error = nil;
    CJSONDeserializer *deserializer = [CJSONDeserializer deserializer];
    [deserializer setNullObject:nil];
    NSArray *objects = [deserializer deserializeAsArray:jsonData error:&error];

    NSMutableArray *result = [NSMutableArray array];

    for (NSDictionary *o in objects) {

        id <EntityProtocol> entity = [[objectClass alloc] init];

        NSDictionary *jsonKeys = objectClass.mapProperties;

        for (NSString *key in jsonKeys.allKeys) {

            NSString *objectProperty = jsonKeys[key];
            NSString *value = o[key];
            if (value)
                [entity setValue:value forKey:objectProperty];
        }

        [result addObject:entity];

    }

    return (NSArray*)result;
}

So I message the parser/mapper like this:

NSArray *objects = [ObjectParser parseData:self.responseData intoObjectsOfType:ObjectEntity.class];

This means that the parser must know what my root object is, which is fine as the object retrieving it from the web service of course has this knowledge.

The above only works for JSON without nested objects, I have been trying to build the parser so that it will take the relationships into account as well, building the needed objects and inserting them into the root object, this needs to be recursive and I keep running into dead ends.

I would like some help to how I could approach this or any insight to as if something like this exists out as a library. Maybe for using or maybe just for tackling the parts I have problems with.

Thank you in advance.

like image 794
RickiG Avatar asked May 26 '11 10:05

RickiG


People also ask

Can we convert JSON to map?

We can easily convert JSON data into a map because the JSON format is essentially a key-value pair grouping and the map also stores data in key-value pairs. Let's understand how we can use both JACKSON and Gson libraries to convert JSON data into a Map.

How do you convert JSON to Java object?

We can convert a JSON to Java Object using the readValue() method of ObjectMapper class, this method deserializes a JSON content from given JSON content String.


1 Answers

Consider using RestKit: http://restkit.org

This framework has all you need — REST and JSON abstractions, object mapping, even Core Data support and a lot of really useful stuff, all implemented in a customizable and elegant manner.

UPDATE: Ok, while writing yet another mapping method, I decided I can't do it anymore and done a small framework. It introspects object's properties, and with a little tuning gives you free pretty description, isEqual/hashCode, free NSCoding support, and allows generating to/from JSON mappers (ok, actually, NSDictionary, but who would use it for something else). All NSNull-checks, missing fields in JSON, new unexpected fields in JSON are handled gracefully and reported properly.

If anybody wants this shared to the public, you could give me some upvotes or comments. I'd do that eventually, but I might consider sharing it faster.

like image 189
jazzcat Avatar answered Sep 19 '22 18:09

jazzcat