Wednesday, February 6, 2013

JSONTransformer - Storing objects in Core Data as JSON

Core Data allows you to store a handful of primitive types (integers, decimals, strings, dates, etc..) but you can also store more complex objects by using the attribute type "transformable". Such objects are persisted by using a "transformer" to convert it to and from NSData (which is what actually gets stored).

Core Data's default transformer is based on archiving / NSKeyedArchiver and as my last post showed NSKeyedArchiver can be incredibly slow compared to other persistence techniques such as JSON-ifying.


Luckily Core Data allows you write custom transformers so you can use any technique you like to convert your objects to and from NSData. It is quite trivial then to write a simple transformer that converts between JSON using JSONKit.


#import "JSONTransformer.h"
#import "JSONKit.h"

@implementation JSONTransformer

+ (BOOL) allowsReverseTransformation {
    return YES;
}

+ (Class) transformedValueClass {
    return [NSData class];
}

- (id) transformedValue:(id)value {
    return [value JSONData];
}

- (id) reverseTransformedValue:(id)value {
    return [value objectFromJSONData];
}

@end


If you are storing an NSDictionary or NSArray in Core Data I'd expect this transformer to give your app performance gains similar to those described in my last post over the default archiving transformer. Specifically for large data I'd expect you to see roughly:
  • 3X reduction in storage size
  • 3X read improvement
  • 10-15X write improvement
Remember that for this to work your NSDictionary or NSArray must contain only simple objects that can be represented as JSON.


No comments: