Latest 1.3.0
License MIT
Platforms ios 5.0, requires ARC

Build Status

Translation between native collections in Objective-C and JSON.

Static methods always return nil if an error occurs (such as JSON could not be
passed, was nil, or was an invalid expected type).

Converting to JSON

Native Types

You can use JSONString or JSONData to get the NSString or NSData encoded
versions in JSON respectively.

NSDictionary *d = @{@"foo": @"bar"};

// {"foo":"bar"}
NSString *JSONString = [d JSONString];

// The same value as above but as a NSData
NSData *JSONData = [d JSONData];

Both methods are available on NSNull, NSNumber, NSArray, NSDictionary,
NSObject, and NSString.

Custom Types

You may also convert any subclass of NSObject:

@interface SomeObject : NSObject

@property NSString *string;
@property int number;

SomeObject *myObject = [SomeObject new];
myObject.string = @"foo";
myObject.number = 123;

// {"string":"foo","number":123}
NSString *json = [myObject JSONString];

If you need to control how custom objects are serialized you may override the
[JSONDictionary] method:

@implementation SomeObject

- (NSDictionary *)JSONDictionary
    return @{
        @"number": self.number,
        @"secret": @"bar",

SomeObject *myObject = [SomeObject new];
myObject.string = @"foo";
myObject.number = 123;

// {"number":123,"secret":"bar"}
NSString *json = [myObject JSONString];

Converting from JSON

Native Types

The simplest way to convert JSON to an object is to run it through NSObject:

NSString *json = @"{"foo":"bar"}";
id object = [NSObject objectWithJSONString:json];

However, if you know the type of the incoming value you should use the
respective class factory (rather than blindly casting):

NSString *json = @"{"foo":"bar"}";
NSDictionary *d = [NSDictionary dictionaryWithJSONString:json];

When using a specific class it will not accept a valid JSON value of an
unexpected type to prevent bugs occuring, for example:

NSString *json = @"{"foo":"bar"}";

// `a` is `nil` because we only intend to decode a JSON array.
NSArray *a = [NSArray arrayWithJSONString:json];

// `b` is an instance of `NSDictionary` but future code will be treating it like
// an `NSArray` which will surely cause very bad things to happen...
NSArray *b = [NSObject objectWithJSONString:json];

Custom Types

Let’s say you have this:

@interface SomeObject : NSObject

@property NSString *string;
@property int number;


The same method that unwraps native types is used except because the static
method [objectWithJSONString:] is called against SomeObject you are saying
that it must unserialize to that type of object.

NSString *json = @"{"string":"foo","number":123};

SomeObject *myObject = [SomeObject objectWithJSONString:json];

// 123

// Do NOT do this. Otherwise you will get an NSDictionary.
// SomeObject *myObject = [NSObject objectWithJSONString:json];

Objects are contructed recursively by first checking to see if the property
exists, if it does and the data is not prefixed with NS it will create another
custom object and continue. This means JSON can be used to unpack simple objects
without any specific code however this has some caveats:

  1. It is dangerous. Not all properties are public or even exist so types can
    be easily missing and cause serious memory error when trying to use the
    unpacked objects.

  2. It will always use the [init] constructor which may be wrong or not even
    available making the object constructions impossible.

A much safer way to unpack objects is to override the [setValue:forProperty:]
method. This allows you to control exactly what logic you need with each

Note: This is is a wrapper for [setValue:forKey:] and will call
[setValue:forKey:] if you have not overridden it.

@implementation SomeObject

- (void)setValue:(id)value forProperty:(NSString *)key
    // Only allow these two properties to be set.
    NSArray *properties = @[@"number", @"string"];
    if ([properties indexOfObject:key] != NSNotFound) {
        [self setValue:value forKey:key];


Pretty Printing

By default serialized JSON will not contain extra spaces which is best for
transmission and storage but it is less readable for debugging. You can generate
pretty JSON by specifying the indent size:

NSDictionary *object = @{@"abc": @"def"};

// {
//   "abc": "def"
// }
NSString *result = [object prettyJSONStringWithIndentSize:2];

Creating Mutable Objects

For every factory method there is a mutable counterpart used for generating
objects that be safely editly directly after unpacking.

NSString *json = @"{"foo":"bar"}";
NSDictionary *d = [NSDictionary dictionaryWithJSONString:json];
NSMutableDictionary *md = [NSMutableDictionary mutableDictionaryWithJSONString:json];

Loading from Files

Each factory method also has a way to generate the object directly from a file:

NSArray *foo = [NSArray arrayWithJSONFile:@"foo.json"];

If the file does not exist, there was an error parsing or the JSON was the wrong
type then nil will be returned.

Futhermore you can create mutable objects from files:

NSMutableArray *foo = [NSMutableArray mutableArrayWithJSONFile:@"foo.json"];

Handling Errors

In most cases you will not run into problems. However, the default behavior is
to return nil and have the error reason suppressed. If you want to handle the
error more safely you can provide a reference to an NSError:

NSError *error;
NSString *result = [object JSONStringOrError:&error];
if (error) {
    // Use these:
    //   error.localizedDescription
    //   error.localizedFailureReason

This works the same way for JSONDataOrError: and JSONDictionaryOrError:.

Latest podspec

    "name": "CollectionFactory",
    "version": "1.3.0",
    "summary": "Translation between native collections in Objective-C and serialized formats like JSON.",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Elliot Chance": "[email protected]"
    "platforms": {
        "ios": "5.0"
    "source": {
        "git": "",
        "tag": "v1.3.0"
    "source_files": "CollectionFactory/*.{h,m}",
    "requires_arc": true

Pin It on Pinterest

Share This