Inherits from NSObject
Declared in SBJson4Parser.h

Overview

Parse one or more chunks of JSON data.

Using this class directly you can reduce the apparent latency for each download/parse cycle of documents over a slow connection. You can start parsing and return chunks of the parsed document before the entire document is downloaded.

Using this class is also useful to parse huge documents on disk bit by bit so you don’t have to keep them all in memory.

JSON is mapped to Objective-C types in the following way:

  • null –> NSNull
  • string –> NSString
  • array –> NSMutableArray
  • object –> NSMutableDictionary
  • true –> NSNumber’s -numberWithBool:YES
  • false –> NSNumber’s -numberWithBool:NO
  • number –> NSNumber

Since Objective-C doesn’t have a dedicated class for boolean values, these turns into NSNumber instances. However, since these are initialised with the -initWithBool: method they round-trip back to JSON properly. In other words, they won’t silently suddenly become 0 or 1; they’ll be represented as ‘true’ and ‘false’ again.

Integers are parsed into either a long long or unsigned long long type if they fit, else a double is used. All real & exponential numbers are represented using a double. Previous versions of this library used an NSDecimalNumber in some cases, but this is no longer the case.

The default behaviour is that your passed-in block is only called once the entire input is parsed. If you set supportManyDocuments to YES and your input contains multiple (whitespace limited) JSON documents your block will be called for each document:

SBJson4ValueBlock block = ^(id v, BOOL *stop) {
    BOOL isArray = [v isKindOfClass:[NSArray class]];
    NSLog(@"Found: %@", isArray ? @"Array" : @"Object");
}

SBJson4ErrorBlock eh = ^(NSError* err) {
    NSLog(@"OOPS: %@", err);
}

id parser = [SBJson4Parser multiRootParserWithBlock:block
                                       errorHandler:eh];

// Note that this input contains multiple top-level JSON documents
id data = [@"[]{}" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];
[parser parse:data];

The above example will print:

  • Found: Array
  • Found: Object
  • Found: Array
  • Found: Object

Often you won’t have control over the input you’re parsing, so can’t make use of this feature. But, all is not lost: if you are parsing a long array you can get the same effect by setting rootArrayItems to YES:

id parser = [SBJson4Parser unwrapRootArrayParserWithBlock:block
                                             errorHandler:eh];

// Note that this input contains A SINGLE top-level document
id data = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];

Note: Stream based parsing does mean that you lose some of the correctness verification you would have with a parser that considered the entire input before returning an answer. It is technically possible to have some parts of a document returned as if they were correct but then encounter an error in a later part of the document. You should keep this in mind when considering whether it would suit your application.

Tasks

Class Methods

multiRootParserWithBlock:errorHandler:

Create a JSON Parser that parses multiple whitespace separated documents. This is useful for something like twitter’s feed, which gives you one JSON document per line.

+ (id)multiRootParserWithBlock:(SBJson4ValueBlock)block errorHandler:(SBJson4ErrorBlock)eh

Parameters

block

Called for each element. Set *stop to YES if you have seen enough and would like to skip the rest of the elements.

eh

Called if the parser encounters an error.

Declared In

SBJson4Parser.h

parserWithBlock:allowMultiRoot:unwrapRootArray:errorHandler:

Create a JSON Parser.

+ (id)parserWithBlock:(SBJson4ValueBlock)block allowMultiRoot:(BOOL)allowMultiRoot unwrapRootArray:(BOOL)unwrapRootArray errorHandler:(SBJson4ErrorBlock)eh

Parameters

block

Called for each element. Set *stop to YES if you have seen enough and would like to skip the rest of the elements.

allowMultiRoot

Indicate that you are expecting multiple whitespace-separated JSON documents, similar to what Twitter uses.

unwrapRootArray

If set the parser will pretend an root array does not exist and the enumerator block will be called once for each item in it. This option does nothing if the the JSON has an object at its root.

eh

Called if the parser encounters an error.

Discussion

This can be used to create a parser that accepts only one document, or one that parses many documents any

Declared In

SBJson4Parser.h

unwrapRootArrayParserWithBlock:errorHandler:

Create a JSON Parser that parses a huge array and calls for the value block for each element in the outermost array.

+ (id)unwrapRootArrayParserWithBlock:(SBJson4ValueBlock)block errorHandler:(SBJson4ErrorBlock)eh

Parameters

block

Called for each element. Set *stop to YES if you have seen enough and would like to skip the rest of the elements.

eh

Called if the parser encounters an error.

Declared In

SBJson4Parser.h

Instance Methods

initWithBlock:processBlock:multiRoot:unwrapRootArray:maxDepth:errorHandler:

Create a JSON Parser.

- (id)initWithBlock:(SBJson4ValueBlock)block processBlock:(SBJson4ProcessBlock)processBlock multiRoot:(BOOL)multiRoot unwrapRootArray:(BOOL)unwrapRootArray maxDepth:(NSUInteger)maxDepth errorHandler:(SBJson4ErrorBlock)eh

Parameters

block

Called for each element. Set *stop to YES if you have seen enough and would like to skip the rest of the elements.

processBlock

A block that allows you to process individual values before being returned.

multiRoot

Indicate that you are expecting multiple whitespace-separated JSON documents, similar to what Twitter uses.

unwrapRootArray

If set the parser will pretend an root array does not exist and the enumerator block will be called once for each item in it. This option does nothing if the the JSON has an object at its root.

maxDepth

The max recursion depth of the parser. Defaults to 32.

eh

Called if the parser encounters an error.

Declared In

SBJson4Parser.h

parse:

Parse some JSON

- (SBJson4ParserStatus)parse:(NSData *)data

Parameters

data

An NSData object containing the next chunk of JSON

@return – SBJson4ParserComplete if a full document was found – SBJson4ParserWaitingForData if a partial document was found and more data is required to complete it – SBJson4ParserError if an error occured.

Discussion

The JSON is assumed to be UTF8 encoded. This can be a full JSON document, or a part of one.

Declared In

SBJson4Parser.h