Slide 1

Slide 1 text

Delighting your users with SBJson 4 Stig Brautaset @stigbra ~ github.com/stig

Slide 2

Slide 2 text

What’s more important to you? Time until your users see the last record? Or until they see the first? ! Do you cut page size to reduce the wait?

Slide 3

Slide 3 text

Download-then-parse Time to first record Time to last record

Slide 4

Slide 4 text

Chunked delivery Time to first record Time to last record

Slide 5

Slide 5 text

Multi-core chunked delivery Time to first record Time to last record

Slide 6

Slide 6 text

Relative time to first record 0 250 500 750 1000 1 record 10 records 100 records 1000 records Chunked delivery Download-then-parse

Slide 7

Slide 7 text

NSJSONSerialisation • Supports NSStream! • But can’t do chunked delivery. • We can do better!

Slide 8

Slide 8 text

SBJson • Chunked delivery since version 3 (in June 2011) • But it was confusing and cumbersome to use… • …with multiple delegates required

Slide 9

Slide 9 text

SBJson 4 • Focus on chunked delivery • Introduces a block-based interface • Drops category & OO interfaces

Slide 10

Slide 10 text

Multi-root JSON id parser = [SBJson4Parser multiRootParserWithBlock:block errorHandler:eh]; ! ! [parser parse:data("[]{")]; // calls block(@[]) ! [parser parse:data("}[]"]; // next part of stream // calls block(@{}) // calls block(@[])

Slide 11

Slide 11 text

Multi-root JSON id parser = [SBJson4Parser multiRootParserWithBlock:block errorHandler:eh]; ! ! [parser parse:data("[]{")]; // calls block(@[]) ! [parser parse:data("}[]"]; // next part of stream // calls block(@{}) // calls block(@[])

Slide 12

Slide 12 text

Use with custom
 NSURLSessionDataDelegate - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dt didReceiveData:(NSData *)data { ! switch ([parser parse: data]) { // handle various returns here… } }

Slide 13

Slide 13 text

–Me, early 2011 “But what if I am consuming a 3rd-party API and they just give me a long list?”

Slide 14

Slide 14 text

Unwrap the root array! id parser = [SBJson4Parser unwrapRootArrayParserWithBlock:block errorHandler:eh]; ! [parser parse:data("[[],{")]; // calls block(@[]) ! [parser parse:data("},true]")]; // calls block(@{}) // calls block(@(YES))

Slide 15

Slide 15 text

Unwrap the root array! id parser = [SBJson4Parser unwrapRootArrayParserWithBlock:block errorHandler:eh]; ! [parser parse:data("[[],{")]; // calls block(@[]) ! [parser parse:data("},true]")]; // calls block(@{}) // calls block(@(YES))

Slide 16

Slide 16 text

Unwrapping is for root-level arrays only!

Slide 17

Slide 17 text

Compromise: Corrupted / incomplete JSON [ {}, [], ***###$#”>P ! ! ! block(@{}) block(@[]) errorHandler(…)

Slide 18

Slide 18 text

SBJson’s Blocks SBJson4ValueBlock block = ^(id obj, BOOL *stop) { if (some_condition) { *stop = YES; } else { // do something with obj } }; ! ! SBJson4ErrorBlock eh = ^(NSError *err) { NSLog(@"OOPS: %@", err); };

Slide 19

Slide 19 text

SBJson4ParserStatus switch ([parser parse:data]) { case SBJson4ParserStopped: case SBJson4ParserComplete: NSLog(“Done!"); case SBJson4ParserWaitingForData: break; case SBJson4ParserError: NSLog(@"Ouch, I'm hurt!"); break; }

Slide 20

Slide 20 text

Two CocoaPods! To allow both version 3 and 4 in the same application.