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

How to Build Fast Hybrid iOS Apps

Loki Meyburg
September 29, 2014

How to Build Fast Hybrid iOS Apps

Loki Meyburg

September 29, 2014
Tweet

More Decks by Loki Meyburg

Other Decks in Programming

Transcript

  1. Their problem wasn't them betting too much on HTML5. !

    Their problem was developing piece of shit apps that happened to use HTML5. - The top comment on HackerNews https://news.ycombinator.com/item?id=4507879
  2. JAVASCRIPT WAS SLOWER THAN SAFARI ! SCROLLING WAS SLOWER THAN

    UISCROLLVIEW ! CACHING DATA WITH HTTPS DIDN’T WORK ! ALSO, THE iPHONE 4S DIDN’T USE LTE HYBRID APPS IN 2012
  3. I think every software shop today should take another look

    at the hybrid approach. ! David Heinemeier Hansson 37Signals https://signalvnoise.com/posts/3743-hybrid-sweet-spot-native-navigation-web-content
  4. URLS = [ ARRAY , OF , URLS , TO

    , CACHE ] ; ! LOOP THROUGH URLS { ! ASYNCHRONOUS REQUEST FOR ( URL ) ; ! } PSEUDOCODE
  5. URLS = [ ARRAY , OF , URLS , TO

    , CACHE ] ; ! LOOP THROUGH URLS { ! ASYNCHRONOUS REQUEST FOR ( URL ) ; ! } PSEUDOCODE PUT THIS IN A QUEUE TO RUN IN THE BACKGROUND
  6. URLS = [ ARRAY , OF , URLS , TO

    , CACHE ] ; ! LOOP THROUGH URLS { ! ASYNCHRONOUS REQUEST FOR ( URL ) ; ! } PSEUDOCODE ANY OF THESE URLS WILL NOW BE STORED TO DISK CACHE ! INSTANT RETRIEVAL WHEN REQUESTED
  7. NSArray *photoList = @[ @"https://s3.amazonaws.com/uifaces/faces/twitter/brad_frost/128.jpg", @"https://s3.amazonaws.com/uifaces/faces/twitter/csswizardry/128.jpg", // … etc …

    ]; for (NSString *photoURL in photoList) { NSURL *url = [NSURL URLWithString:photoURL]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:5.0]; ! [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if (!connectionError) { // Here's the image! // UIImage *image = [UIImage imageWithData:data]; } }]; } REAL CODE LIST OF URLS ASYNC REQUEST
  8. FOR MORE PRECISE CACHE CONTROL ! USE HTTP CACHE CONTROL

    HEADERS REQUEST CACHE HEADERS If-Modified-Since If-None-Match ! RESPONSE CACHE HEADERS Cache-Control Last-Modified Check http://nshipster.com/nsurlcache/ for details on each cache header
  9. Untold numbers of developers have hacked together an awkward, fragile

    system for network caching functionality, all because they weren't aware that NSURLCache could be setup in two lines and do it 100× better. http://nshipster.com/nsurlcache/
  10. Applications that do not have special caching requirements or constraints

    should find the default shared cache instance acceptable. https://developer.apple.com/library/ios/documentation/cocoa/Reference/Foundation/Classes/ NSURLCache_Class/index.html#/apple_ref/occ/clm/NSURLCache
  11. ADD YOUR FONT TO YOUR APP 1 “Asap” IS THE

    FONT I’M USING IN THIS PRESENTATION
  12. suppressesIncrementalRendering: YES A boolean value indicating whether the web view

    suppresses content rendering until it is fully loaded into memory. ! When used properly, suppressing incremental rendering can make web views look more like native views.
  13. WHEN MAKING YOUR REQUEST SHOW A LOADING INDICATOR AND HIDE

    THE WEBVIEW - (void) loadWebView { ! // suppress incremental rendering self.myWebView.suppressesIncrementalRendering = YES; ! // hide webview self.myWebView.alpha = 0.0f; ! // Lets show a loading indicator activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray]; activityIndicator.center = self.view.center; [activityIndicator startAnimating]; [self.view addSubview:activityIndicator]; } SUPPRESS INCREMENTAL RENDERING HIDE WEBVIEW SHOW SPINNER
  14. WHEN YOUR PAGE HAS LOADED HIDE THE LOADING INDICATOR AND

    FADE IN THE WEBVIEW - (void) webViewDidFinishLoad:(UIWebView *)webView { [activityIndicator removeFromSuperview]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.1]; webView.alpha = 1.0f; [UIView commitAnimations]; } HIDE LOADING SPINNER SHOW WEBVIEW
  15. DONT DO THIS <head> . . . <meta content=“Post" name=“app-page-title”

    /> <meta content=“NewComment" name=“app-right-button” /> </head>
  16. DONT DO THIS <head> . . . <meta content=“Post" name=“app-page-title”

    /> <meta content=“NewComment" name=“app-right-button” /> </head> YOU ALREADY KNOW WHAT THE TITLE AND BUTTON SHOULD BE BEFORE THE PAGE HAS LOADED!
  17. PUT IT IN THE URL OR AS A DATA ATTRIBUTE

    <a href=‘/post/123’ data-title=‘News Feed’ data- right-button=‘NewComment’> /post/123?title=Post&right_button=NewComment
  18. THE URL LOADING SYSTEM SUPPORTS THE FOLLOWING SCHEMES ftp:// for

    File Transfer Protocol http:// for Hypertext Transfer Protocol https:// for Hypertext Transfer Protocol with encryption data:// for data URLs
  19. THE URL LOADING SYSTEM SUPPORTS THE FOLLOWING SCHEMES ftp:// for

    File Transfer Protocol http:// for Hypertext Transfer Protocol https:// for Hypertext Transfer Protocol with encryption data:// for data URLs localimg:// YOU CAN CREATE YOUR OWN SCHEME FOR LOADING LOCAL IMAGES
  20. CREATE A CUSTOM NSURLProtocol CLASS 1 REGISTER YOUR PROTOCOL 2

    [NSURLProtocol registerClass:[LMURLImageProtocol class]]; UPDATE YOUR HTML 3 <img src=“localimg://ourimage.png” /> Example can be found at: http://cloud.loki.io/XlcY
  21. http://www.lokimeyburg.com/Stacker/ Stacker is an open source project I created to

    kickstart the development of hybrid native/web iPhone apps
  22. UPDATES ! WKWebView support only a few days away •

    Checkout the `feature/wkwebview` branch • Will be backwards compatible with iOS 7 ! New tutorial on building a `Log In` screen • Checkout the Stacker blog