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

Hybrid mobile applications for a fast development

Hybrid mobile applications for a fast development

Learn about the steps we followed on 8fit to have a mobile web-app solution for our platform with a real mobile experience.

B0a336761194918a853deeff1f22b537?s=128

Pedro Piñera Buendía

December 19, 2014
Tweet

More Decks by Pedro Piñera Buendía

Other Decks in Programming

Transcript

  1. Hybrid Mobile Applications for a fast development - 8fit @pepibumur

    @8fit_app “Any application that can be written in JavaScript, will eventually be written in JavaScript” Atwood's Law
  2. About me // Personal var name = "Pedro Piñera" var

    email = "pepi@8fit.com" // Professional var current_position = "Mobile Lead Dev at 8fit" var github = "github.com/pepibumur" var website = "www.ppinera.es" var experience = [ "Objective-C", "Swift", "Java"] var weak_experience = [ "Ruby", "Javascript"]
  3. A bit of history... We need some context, don't we?

  4. A long time ago... In 2010 (not so far)

  5. Teambox By Pablo Villalba

  6. Redbooth Full rebranding in 2014

  7. None
  8. 8fit

  9. 8fit Customized workout plans and healthy daily meals

  10. 8fit Customized workout plans and healthy daily meals Cheaper than

    a trainer / Better than a gym
  11. 8fit Customized workout plans and healthy daily meals Cheaper than

    a trainer / Better than a gym For Android and iOS
  12. 8fit Customized workout plans and healthy daily meals Cheaper than

    a trainer / Better than a gym For Android and iOS Developed using Web technologies
  13. None
  14. Why web?

  15. What did we need for 8fit? » Test the MVP

    ! " » Launch an initial version ASAP # » Be fast on the development/deployment $ » With limited resources % % %
  16. None
  17. Knowledge » HTML ( & Jade ) » CSS (

    & Sass ) » JS ( & Coffee ) » Rails » Some about systems » No mobile knowledge
  18. Web Application (Javascript SPA) » They knew about web (and

    had enough knowledge to respect the mobile experience) » They had to develop only one application » They could launch updates on air (f*** reviews) » They just only needed a bit of mobile knowledge
  19. Index » Stack (web & mobile) » Building your communication

    bridge » Debugging » Pitfalls and recommendations » Results » Conclussions » ! :paella: !
  20. Stack web

  21. SPA Single Page App

  22. None
  23. None
  24. Advantages » Chunking: Fragments of HTML instead of a big

    page » Controllers: MVC or MVVM patterns instead of handling a complex DOM » Templates: Binding data to HTML templates » Routing: Custom navigation preserving web state » Local storage: capabilities of storing data on a browser for performance and offline access replace cookies and intensive data loads from web server
  25. None
  26. Backbone + Underscore + JQuery But there're many options: Ember,

    Angular, Ionic, ...
  27. Structure » Fonts » Images » Javascripts (Collections, Controllers, Helpers,

    Models, Routers, Lib, ...) » Sounds » Stylesheets » Templates (Jade files) » Translations
  28. Structure » Fonts » Images » Javascripts (Collections, Controllers, Helpers,

    Models, Routers, Lib, ...) -> application.js » Sounds » Stylesheets -> -> application.css » Templates (Jade files) -> templates.js » Translations -> -> translations.js
  29. None
  30. Convert from Coffeescript to Javascript

  31. Convert from Coffeescript to Javascript Convert from Sass to CSS

  32. Convert from Coffeescript to Javascript Convert from Sass to CSS

    Uglify and Minify Javascript
  33. Convert from Coffeescript to Javascript Convert from Sass to CSS

    Uglify and Minify Javascript Concatenate files
  34. Convert from Coffeescript to Javascript Convert from Sass to CSS

    Uglify and Minify Javascript Concatenate files ≈ 1000 plugins !
  35. None
  36. None
  37. None
  38. How can we make 8fit mobile?

  39. How can we make 8fit mobile? Titanium

  40. How can we make 8fit mobile? Titanium Appcelerator

  41. How can we make 8fit mobile? Titanium Appcelerator Sencha Touch

  42. How can we make 8fit mobile? Titanium Appcelerator Sencha Touch

    PhoneGap cd hello cordova platform add ios cordova plugin add org.apache.cordova.network-information cordova build ios cordova prepare ios cordova compile ios
  43. How can we make 8fit mobile? Titanium Appcelerator Sencha Touch

    PhoneGap Custom
  44. How can we make 8fit mobile? Titanium Appcelerator Sencha Touch

    PhoneGap Custom (A pelo)
  45. None
  46. None
  47. Not so hare-brained... » Build projects for Android/iOS » Build

    a communication layer » Add new controllers progressively » We had a mobile developer (to suffer from Apple certificates and Android Studio)
  48. Build your iOS/Android basic web app (In 3 steps)

  49. 1. File > Create Project > Empty project

  50. 2. Add a webview that loads the URL Android webView.getSettings().setJavaScriptEnabled(true);

    webView.getSettings().setAppCacheEnabled(true); webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); webView.getSettings().setAllowFileAccess(true); Boolean remoteDebuggingSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; if(remoteDebuggingSupported) { webView.setWebContentsDebuggingEnabled(true); } clearCacheIfFirstRun(); webView.loadUrl("https://www.8fit.com/a/#");
  51. 2. Add a webview that loads the URL iOS -

    (UIWebView*)webView { if (!_webView) { _webView = [[UIWebView alloc] initForAutoLayout]; _webView.delegate = self; _webView.scrollView.scrollEnabled = NO; _webView.contentMode = UIViewContentModeScaleAspectFit; _webView.scalesPageToFit = YES; self.webView.delegate = self; NSURL *webURL = [NSURL URLWithString:WEB_APP_URL]; NSURLRequest *request = [NSURLRequest requestWithURL:webURL]; [_webView loadRequest:request]; } return _webView; }
  52. 3. Build and deploy » Upload the store assets !

    » Setup your Keystores/Release certificates " » Generate a new build and upload # » $ $ $
  53. I know how to do that man

  54. Not everything can be made using Web

  55. Push Notifications !

  56. In App Purchases !

  57. HealthKit/GoogleFit !

  58. Interaction

  59. Connecting Web ! & Mobile ! worlds

  60. Communication Bridge (show me more code!)

  61. Android // Communication Java -> Javascript webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JavascriptInteractor(), "NativeBridge");

    class JavascriptInteractor { @JavascriptInterface public void buyIAPProduct(String productId) { // MyPaymentsController.buy... } } // Communication Java -> Javascript public void loadJS(String js) { webView.loadUrl("javascript:"+js); }
  62. Android » Asking for a payment NativeBridge.buyIAPProduct("pro_subscription_1mo"); » Reporting payment

    webview.loadJS("Ef.vent.trigger('payment:completed', "+payment.toString()+")")
  63. We can expose Java to Javascript But cannot expose Javascript

    to Java
  64. iOS (Why do you make it so difficult?.. )

  65. iOS UIWebViewDelegate - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { }

  66. iOS UIWebViewDelegate + Custom URL Scheme - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest

    *)request navigationType:(UIWebViewNavigationType)navigationType { // eightfit://buyiapproduct?product_id=pro_subscription_1mo BOOL isNativeBridgeURL = [URLMatcher isForBridge:request.URL.absoluteURL]; if (isNativeBridgeURL){ [JLRoutes routeURL:request.URL.absoluteURL]; return NO; } return YES; }
  67. iOS UIWebViewDelegate + Custom URL Scheme github.com/joeldev/JLRoutes [JLRoutes addRoute:@"/buyiapproduct/:product_id" handler:^BOOL(NSDictionary

    *parameters) { NSString *productId = parameters[@"product_id"]; // defined in the route by specifying ":product_id" [PaymentsController buyProduct:product_id withCompletion:^void (NSError *error) { // Notify JS about the result }]; return YES; // return YES to say we have handled the route }];
  68. None
  69. Some details » Bidirectional communication (question / response)

  70. Some details » Bidirectional communication (question / response) » No

    way to expose Javascript to Mobile
  71. Some details » Bidirectional communication (question / response) » No

    way to expose Javascript to Mobile » Event handlers (JQuery, Backbone, ...)
  72. Some details » Bidirectional communication (question / response) » No

    way to expose Javascript to Mobile » Event handlers (JQuery, Backbone, ...) » No type validation
  73. Something's missing

  74. Something's missing How does Javascript know 1) The app version

    2) The supported features ?
  75. User-Agent » Has the device support for Camera? » Does

    the app version support Payments? 8fit-iOS-8.1/iPhone-6/1.2.3 (iap, push, conn, res)
  76. Some examples of Controllers » Payments (IAP)

  77. Some examples of Controllers » Payments (IAP) » Video Player

  78. Some examples of Controllers » Payments (IAP) » Video Player

    » Sound Player
  79. Some examples of Controllers » Payments (IAP) » Video Player

    » Sound Player » Music Player
  80. Some examples of Controllers » Payments (IAP) » Video Player

    » Sound Player » Music Player » Push Notifications » Login with Facebook » Resources Downloader
  81. Coming Controllers » Frontend Controller » HealthKit/Google Fit integration »

    Interactive Workouts » ...
  82. None
  83. Dealing with two contexts » Native » Javascript -> Native

  84. Dealing with two contexts » Native: » IDE Debugging Tools

    » Javascript -> Native » Chrome Inspector (Android) » Safari Web Inspector (iOS)
  85. What can I do? » Force calls to the bridge

    » Test if returned responses » Emulate the User-Agent » Everything on a real device
  86. None
  87. None
  88. Pitfalls (and recommendations)

  89. 1) Native doesn't know about the JS Recommendation » Document

    the bridge: » Methods » Parameters » Parameters Types
  90. 2) Need a bit of Mobile Knowledge Recommendation » If

    you don't have a mobile developer: 1.Learn it, it's not very difficult Alternative: PhoneGap and some other Frameworks (plugins)
  91. 3) Experience close to mobile but not the same Recommendation

    » Move to native only the components/views where you want to have a trully mobile experience (e.g Interactive workouts)
  92. 4) Test the offline experience Recommendations » Show an alert

    if the first time the app is opened there's no internet connection » Pay attention on your frontend persistence
  93. 5) Be careful with the cache Recommendations » Clean it

    periodically » Force the renaming your files on every build
  94. 8fit Results We owe you own, Javascript

  95. First trainings are free Users pay $25 for 3 Months

    of PRO » Unlimited workouts » Meals plans » Personal Trainer support
  96. 100.000 users In our first 6 months

  97. 100.000 users In our first 6 months (Reaching 1000 signups

    every day)
  98. $7.500 Monthly revenue

  99. $7.500 Monthly revenue 88% Renewal rate

  100. $7.500 Monthly revenue 88% Renewal rate $30-40 Customer acquisition cost

  101. $7.500 Monthly revenue 88% Renewal rate $30-40 Customer acquisition cost

    $80-100 Customer lifetime value
  102. Mobile install ads For every $1.000 invested we have a

    $3.000 return
  103. None
  104. 6 Team members

  105. 6 Team members 2 years to live with cash in

    hand
  106. 6 Team members 2 years to live with cash in

    hand 230k forecast for 2015
  107. 6 Team members 2 years to live with cash in

    hand 230k forecast for 2015 1 million users by March 2016
  108. Conclussions » Javascript is not a bad solution for the

    beginning.
  109. Conclussions » Javascript is not a bad solution for the

    beginning. » It might be restrictive in the future interactivity, animations, ...
  110. Conclussions » Javascript is not a bad solution for the

    beginning. » It might be restrictive in the future interactivity, animations, ... » Analyze your resources before starting a mobile solution. Try to have an expert on each field (with multidisciplinary skills)
  111. Conclussions » Javascript is not a bad solution for the

    beginning. » It might be restrictive in the future interactivity, animations, ... » Analyze your resources before starting a mobile solution. Try to have an expert on each field (with multidisciplinary skills) » Get ready for the battle with Javascript! We are getting amazing results
  112.  One More Thing...

  113. WKWebView (iOS 8 Only) » Performance: Much faster! » More

    Javascript support // Evaluate Javascript - (void)evaluateJavaScript:(NSString *)js completionHandler:(void (^)(id, NSError *))handler; // Inject Javascript NSString *scriptSource = @"alert('WKWebView JS Call!')"; WKUserScript *userScript = [[WKUserScript alloc] initWithSource:scriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES]; [wkWebView.configuration.userContentController addUserScript:userScript];
  114. Questions? Doubts? Suggestions?

  115. Thanks ! Try 8fit - It's free!