Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SBJson 4: Don't make me wait!

SBJson 4: Don't make me wait!

How SBJson 4 can help you get happy users.

F83cfcc2713f34cf9db3f6488383cee1?s=128

Stig Brautaset

March 05, 2014
Tweet

Transcript

  1. SBJson 4: Don’t make me wait! Stig Brautaset ~ @stigbra

  2. Who am I? Started SBJson in 2007. Compulsively tinkered with

    it since.
  3. Fun facts 7 years on • 1012 commits • 4

    major releases • 30 contributors • 3247 “stars” • 688 “forks”
  4. –Every non-trivial app, ever. “Download a list of records &

    display them to the user.”
  5. What’s more important to your users? • Time until they

    see the last record? • Or until they see the first?
  6. The trouble with pagination • Repeated connection overhead • Records

    fall in the cracks between pages • Records appear on two consecutive pages
  7. Download-then-parse Time to first record Time to last record

  8. Chunked delivery Time to first record Time to last record

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

    record
  10. 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
  11. NSJSONSerialisation • Supports NSStream! • But can’t do chunked delivery.

    • We can do better!
  12. SBJson 3 • Chunked delivery since June 2011 :-) •

    But it was confusing and cumbersome to use… :-/ • …requiring multiple delegates chained together :-(
  13. SBJson 4 • Drops category & OO interfaces • Focus

    on chunked delivery • Introduces a block-based interface • Built specifically for two primary use cases
  14. Multi-root JSON [1,2,3] {“foo”:42} [true,false]

  15. Multi-root JSON id parser =
 [SBJson4Parser
 multiRootParserWithBlock:block
 errorHandler:eh];

  16. Multi-root JSON [parser parse:data("[]{")];
 // calls block(@[]) [parser parse:data("}[]"]; //

    next part of stream
 // calls block(@{})
 // calls block(@[])
  17. Multi-root JSON [parser parse:data("[]{")];
 // calls block(@[]) [parser parse:data("}[]"]; //

    next part of stream
 // calls block(@{})
 // calls block(@[])
  18. Compromise: “garbage after JSON” []**xx block(@[])
 errorHandler(…)

  19. –Johnny Appleseed “What if I am using a 3rd-party API

    that just gives me a long list?”
  20. Root array chunks [ [1,2,3], {“foo”:42}, [true,false] ]

  21. Unwrap the root array! id parser =
 [SBJson4Parser
 unwrapRootArrayParserWithBlock:block
 errorHandler:eh];

  22. Unwrap the root array! [parser parse:data("[[],{")];
 // calls block(@[]) [parser

    parse:data("},true]")];
 // calls block(@{})
 // calls block(@(YES))
  23. Unwrap the root array! [parser parse:data("[[],{")];
 // calls block(@[]) [parser

    parse:data("},true]")];
 // calls block(@{})
 // calls block(@(YES))
  24. Compromise: Corrupted / incomplete JSON [
 {},
 [],
 ***###$#”>P block(@{})


    block(@[])
 errorHandler(…)
  25. Unwrapping is for root-level arrays only!

  26. SBJson’s Blocks SBJson4ValueBlock block = ^(id obj, BOOL *stop) {


    if (some_condition) {
 *stop = YES;
 } else {
 // do something with obj
 }
 };
  27. SBJson4ParserStatus switch ([parser parse:data]) {
 case SBJson4ParserStopped:
 case SBJson4ParserComplete:
 NSLog(“Done!");


    case SBJson4ParserWaitingForData:
 break;
 case SBJson4ParserError:
 NSLog(@"Ouch, I'm hurt!");
 break;
 }
  28. Use with custom
 NSURLSessionDataDelegate - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dt didReceiveData:(NSData

    *)data { 
 switch ([parser parse: data]) { // handle various returns here… } }
  29. Two CocoaPods! To allow both version 3 and 4 in

    the same application.
  30. http://www.flickr.com/photos/dullhunk/202872717/