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) {
    NSLog(@"Found: %@", @([v isKindOfClass:[NSArray class]]));
};
SBJson4ErrorBlock eh = ^(NSError* err) {
    NSLog(@"OOPS: %@", err);
 }

 id parser = [SBJson4Parser parserWithBlock:block
                             manyDocuments:YES
                            rootArrayItems:NO
                              errorHandler:eh];

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

The above example will print:

  • Found: YES
  • Found: NO
  • Found: YES
  • Found: NO

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 parserWithBlock:block
                             manyDocuments:NO
                            rootArrayItems:YES
                              errorHandler:eh];

 // Note that this input contains A SINGLE top-level document
 NSData *json = [@"[[],{},[],{}]" 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:

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

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.

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:

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

Create a JSON Parser.

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

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.

Declared In

SBJson4Parser.h

unwrapRootArrayParserWithBlock:errorHandler:

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

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

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:

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

Create a JSON Parser.

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:

- (SBJson4ParserStatus)parse:(NSData *)data
Discussion

Parse some JSON

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

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.

Declared In

SBJson4Parser.h