SBJson 4:
Don’t make me wait!
Stig Brautaset ~ @stigbra
Slide 2
Slide 2 text
Who am I?
Started SBJson in 2007.
Compulsively tinkered with it since.
Slide 3
Slide 3 text
Fun facts 7 years on
• 1012 commits
• 4 major releases
• 30 contributors
• 3247 “stars”
• 688 “forks”
Slide 4
Slide 4 text
–Every non-trivial app, ever.
“Download a list of records &
display them to the user.”
Slide 5
Slide 5 text
What’s more important to your users?
• Time until they see the last record?
• Or until they see the first?
Slide 6
Slide 6 text
The trouble with pagination
• Repeated connection overhead
• Records fall in the cracks between pages
• Records appear on two consecutive pages
Slide 7
Slide 7 text
Download-then-parse
Time to first record
Time to last record
Slide 8
Slide 8 text
Chunked delivery
Time to first record
Time to last record
Slide 9
Slide 9 text
Multi-core chunked delivery
Time to first record
Time to last record
Slide 10
Slide 10 text
Relative time to first record
0
1.25
2.5
3.75
5
1 record 2 records 3 records 4 records 5 records
Chunked delivery Traditional
Slide 11
Slide 11 text
NSJSONSerialisation
• Supports NSStream!
• But can’t do chunked delivery.
• We can do better!
Slide 12
Slide 12 text
SBJson 3
• Chunked delivery since June 2011 :-)
• But it was confusing and cumbersome to use… :-/
• …requiring multiple delegates chained together :-(
Slide 13
Slide 13 text
SBJson 4
• Drops category & OO interfaces
• Focus on chunked delivery
• Introduces a block-based interface
• Built specifically for two primary use cases
Slide 14
Slide 14 text
Multi-root JSON
[1,2,3]
{“foo”:42}
[true,false]
Slide 15
Slide 15 text
Multi-root JSON
id parser =
[SBJson4Parser
multiRootParserWithBlock:block
errorHandler:eh];
Slide 16
Slide 16 text
Multi-root JSON
[parser parse:data("[]{")];
// calls block(@[])
[parser parse:data("}[]"]; // next part of stream
// calls block(@{})
// calls block(@[])
Slide 17
Slide 17 text
Multi-root JSON
[parser parse:data("[]{")];
// calls block(@[])
[parser parse:data("}[]"]; // next part of stream
// calls block(@{})
// calls block(@[])
Slide 18
Slide 18 text
Compromise:
“garbage after JSON”
[]**xx
block(@[])
errorHandler(…)
Slide 19
Slide 19 text
–Johnny Appleseed
“What if I am using a 3rd-party API that just gives me a long list?”
SBJson’s Blocks
SBJson4ValueBlock block = ^(id obj, BOOL *stop) {
if (some_condition) {
*stop = YES;
} else {
// do something with obj
}
};
Slide 27
Slide 27 text
SBJson4ParserStatus
switch ([parser parse:data]) {
case SBJson4ParserStopped:
case SBJson4ParserComplete:
NSLog(“Done!");
case SBJson4ParserWaitingForData:
break;
case SBJson4ParserError:
NSLog(@"Ouch, I'm hurt!");
break;
}
Slide 28
Slide 28 text
Use with custom
NSURLSessionDataDelegate
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dt
didReceiveData:(NSData *)data {
switch ([parser parse: data]) {
// handle various returns here…
}
}
Slide 29
Slide 29 text
Two CocoaPods!
To allow both version 3 and 4 in the
same application.