Cocoa JSON Framework

JSON (JavaScript Object Notation) is a lightweight data-interchange format. This framework contains a collection of categories adding full JSON support to Cocoa by extending existing Objective-C classes. This site documents version __VERSION__ of the framework.

Basic usage

Linking to the JSON framework and importing the <JSON/JSON.h> header provides the following main methods.

Generating JSON

The following methods are added as a category on NSArray and NSDictionary:

- (NSString *)JSONRepresentation;
Returns an NSString instance containing the receiver encoded in JSON. Please read the note on mapping NSDictionary instances to JSON objects.
- (NSString *)JSONRepresentationWithOptions:(NSDictionary *)opts;
Like -JSONRepresentation, but allows you to control the look of the produced JSON. Options are turned on by providing an instance that responds YES when sent -boolValue. (Usually this would be an NSNumber, but it could be an NSString if you find it more convenient.) Valid options are:
SpaceBefore
When encoding a dictionary, adds a space before the ':' that separates the key from its associated value.
SpaceAfter
When encoding a dictionary, adds a space after the ':' that separates the key from its associated value. Also adds a space between the ',' and the next item for both arrays and dictionaries. (Except when MultiLine is also active.)
MultiLine
Produces human-readable JSON by using a multi-line format. Each array member and dictionary key/value pair is output on its own line, indented properly.
Pretty
A short-cut that turns on SpaceBefore, SpaceAfter and MultiLine all in one go.

Parsing JSON

The following methods are added as a category on NSString.

- (id)JSONValue;
Returns either an NSArray or NSDictionary decoded from the JSON in the receiver. Throws an error if the receiver does not contain valid JSON text.
- (id)JSONValueWithOptions:(NSDictionary *)opts;
Like -JSONValue but allows you to set options controlling the parsing. Valid options are:
MaxDepth
Throws an exception if the JSON string that is decoded is nested deeper than the given level. Set it to zero for "unlimited" nesting. The default value is 512.

JSON fragments

Strictly speaking JSON must have exactly one top-level container. (Either an array or an object.) Bare nulls, numbers, booleans and strings are not valid JSON on their own. It can be quite convenient to pretend that such fragments are valid JSON however. The following methods will let you do so:

- (NSString *)JSONFragment;
Added to NSNull, NSNumber & NSString, and returns an NSString containing the receiver encoded into a JSON text fragment. (See mapping note on encoding NSNumbers.)
- (id)JSONFragmentValue;
Added to NSString, and returns the JSON fragment decoded into an instance of either NSArray, NSDictionary, NSNull, NSNumber, or NSString.

Mapping between JSON and Objective-C types

Here's how the distinct JSON types map to Objective-C types.

Object <=> NSDictionary
In JSON the keys of an object must be strings. NSDictionary keys need not be, but attempting to convert an NSDictionary with non-string keys into JSON will throw an exception.
Array <=> NSArray
String <=> NSString
Null <=> NSNull
Boolean <=> NSNumber
The JSON boolean "true" and "false" values are represented by NSNumber instances created with the +numberWithBool: method.
Number <= NSNumber
Number => NSDecimalNumber
Any NSNumber instance other than the previously mentioned booleans will be converted to a JSON number the way you would expect. JSON numbers turn into NSDecimalNumber instances.

Limitations

This framework is limited to parsing strict JSON. (Other than the above mentioned support for JSON fragments.) For example, it does not support trailing commas in arrays or objects.

Performance

I strongly believe in correctness first, speed later and that was very much the angle of attack when creating this framework. Then out of the blue Jens Alfke emailed me a couple of patches providing a serious performance boost. I've made sure to keep up this performance in any later changes.

Below are some performance measurements comparing this framework to Blake Seely's BSJSONAdditions. These are the same strings that Marc Lehmann used comparing JSON::XS to its competitors. These measurements were taken with the revision r3210 of trunk.

  short string long string (~12k)
  encode decode encode decode
BSJSONAdditions 10488.8 4134.0 70.5 3.7
SBJSON 39858.1 23319.8 714.3 555.8

In BSJSONAdditions' defence, its parser allows you to embed C-style comments in the JSON text. This can be very handy for configuration files, for example, but makes the parser a little more complicated. SBJSON does not support them as they are not part of the JSON spec.

Resources

Bugs

Currently none known. If you find one, feel free to report it via email.

Author

Cocoa JSON Framework is written by yours truly, Stig Brautaset, and released under the revised BSD license. You are welcome to email me.

http://code.brautaset.org lists more code by me. I occasionally announce new projects on my blog. It also contains the definite list of ways to contact me.