SBJson4Parser Class Reference
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
-
+ parserWithBlock:allowMultiRoot:unwrapRootArray:errorHandler:
Create a JSON Parser.
-
+ 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.
-
+ unwrapRootArrayParserWithBlock:errorHandler:
Create a JSON Parser that parses a huge array and calls for the value block for each element in the outermost array.
-
– initWithBlock:processBlock:multiRoot:unwrapRootArray:maxDepth:errorHandler:
Create a JSON Parser.
-
– parse:
Parse some JSON
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.
See Also
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
See Also
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.
See Also
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