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

Raymond Camden: Best Practices for Apache Cordova/PhoneGap Development

1fa9cb8c7997c8c4d3d251fb5e41f749?s=47 Realm
March 01, 2017

Raymond Camden: Best Practices for Apache Cordova/PhoneGap Development

Video: https://www.youtube.com/watch?v=gRsnUhVeD_g

Speaker: Raymond Camden is a developer advocate for IBM. His work focuses on LoopBack, API Connect, Bluemix, hybrid mobile development, Node.js, HTML5, and web standards in general. He's a published author and presents at conferences and user groups on a variety of topics.
Raymond can be reached at his blog (www.raymondcamden.com), @raymondcamden on Twitter, or via email at raymondcamden@gmail.com.

Abstract: In this session, I'll discuss best practices, tips, and suggestions, for working with hybrid mobile applications and the Apache Cordova (and PhoneGap) frameworks. I'll discuss testing, offline support, data management, a bit of UI and UX as well, and point out resources for learning more.

Twitter Link: https://twitter.com/raymondcamden

1fa9cb8c7997c8c4d3d251fb5e41f749?s=128

Realm

March 01, 2017
Tweet

Transcript

  1. What they didn't tell you about Cordova! I started building

    hybrid apps and you won't believe what happened next!!
  2. Raymond Camden! •  Developer Advocate for IBM! •  LoopBack, OpenWhisk,

    Bluemix, Cordova/ PhoneGap, Node, and web stuff in general! •  Blogging at raymondcamden.com! •  Tweeting at @raymondcamden!
  3. None
  4. Hybrid Dev is Easy!

  5. Decent Hybrid Dev?!

  6. None
  7. https://www.flickr.com/photos/motoyen/3763218863!

  8. Our Tools! •  Offline Detection/Support! •  Client-Side Storage! •  Internationalization!

    •  UI/UX! •  Performance! •  Etc.!
  9. Before we begin…!

  10. HTML, JS, CSS! •  That web stuff… it’s kind of

    important! •  Know everything!! •  Mozilla Developer Network (developer.mozilla.org)! •  CanIUse (caniuse.com)!
  11. Repeat After Me! (no - seriously)!

  12. You must use dev tools! Period!

  13. Offline - it's not just for breakfast anymore!

  14. The Network is Evil! •  Your app runs on the

    device - it doesn't matter whether you're online or not! •  Your app may start in one state - and enter another! •  You may be online, but in a really, really crappy manner! •  You may be online, but behind a wifi captive portal!
  15. What to worry about...! •  Am I online?! •  How

    well am I online?! •  How much data do I need to transfer?! •  Can I get by with part of it?!
  16. Oh yeah...! •  What if your server is offline?! • 

    What if your server is online but returning crap?! •  What if your third party server - ditto...!
  17. Basically...!

  18. None
  19. What do you do?! •  Banking apps! •  Weather apps!

    •  Social Media/IM apps!
  20. Code time!! •  network-information! •  detects type (how well?)! • 

    detects changes!
  21. Demos!

  22. A Place for Your Stuff!

  23. Client-Side Storage! •  A great way to handle offline! • 

    A great way to boost performance!
  24. Types of Storage! •  Cookies! •  WebStorage! •  WebSQL! • 

    IndexedDB! •  File System! •  SQLite!
  25. Cookies! •  Yes - seriously! •  Just FYI! •  MDN

    Library - https://developer.mozilla.org/en-US/docs/Web/API/ Document/cookie/Simple_document.cookie_framework!
  26. WebStorage! •  LocalStorage/SessionStorage! •  Super easy!! •  iOS 8+ kills

    it though (cuz - iOS)! •  Tips: Use for caching - but assume it won't persist!
  27. WebSQL! •  Dead spec :(! •  But guess what -

    still works (http://caniuse.com/#feat=sql-storage)! •  But use SQLite instead!
  28. IndexedDB! •  The future of web storage!! •  Easy as

    rocket science!! •  Really, really, really, really bad iOS 9 support (fixed in 10)!
  29. File System! •  CRUD for the File System! •  You

    can do everything! •  It works!
  30. None
  31. SQLite! •  Just works!! •  (As long as you know

    SQL ;)! •  cordova-sqlite-storage!
  32. Examples!

  33. WebStorage!

  34. if(window.localStorage) { var numHits = localStorage.getItem("numHits"); if(!numHits) numHits=0; else numHits

    = parseInt(numHits, 10); numHits++; localStorage.setItem("numHits",numHits); $("#resultDiv").text("You have visited this site "+numHits +" times."); }
  35. IndexedDB!

  36. var openRequest = indexedDB.open("ora_idb1",1); openRequest.onupgradeneeded = function(e) { var thisDB

    = e.target.result; console.log("running onupgradeneeded"); if(!thisDB.objectStoreNames.contains("people")) { var peopleOS = thisDB.createObjectStore("people", {keyPath: "email"}); } }
  37. var transaction = db.transaction(["people"],"readwrite"); //Ask for the objectStore var store

    = transaction.objectStore("people"); //Define a person var person = { name:name, email:email, created:new Date().getTime() } //Perform the add var request = store.add(person); request.onerror = function(e) { console.log("Error",e.target.error.name); //some type of error handler } request.onsuccess = function(e) { console.log("Woot! Did it"); }
  38. WebSQL!

  39. db = window.openDatabase("notestrap", "1.0", "Note App", 5*1024*1024); //Handle initial creation

    and then load up the notes db.transaction(function(tx) { tx.executeSql("create table if not exists notes(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, body TEXT, updated DATE)"); }, dbError,function(tx) { getNotes(); });
  40. function getNotes(search) { db.readTransaction(function(tx) { if(!search) { tx.executeSql("select id,title,body,updated from

    notes order by updated desc", [], displayNotes); } else { var fuzzy = "%" + search + "%"; tx.executeSql("select id,title,body,updated from notes where title like ? or body like ? order by updated desc", [fuzzy,fuzzy], displayNotes); } }, dbError); }
  41. File System!

  42. None
  43. "Use the Library, Luke!"! •  Lockr (LocalStorage only)! •  Dexie

    (IDB)! •  localForage! •  pouchdb (syncs!)!
  44. Advertisement! Book and video available at raymondcamden.com!

  45. Spoiler...!

  46. None
  47. But wait...! •  They speak a different language (that's cool)!

    •  They use a different unit of measurement (that's mostly cool too)! •  "NASA lost a $125 million Mars orbiter because a Lockheed Martin engineering team used English units of measurement while the agency's team used the more conventional metric system for a key spacecraft operation..." (oh crap)! •  They write numbers differently (that's just insane)!
  48. Examples:! •  1,000,000.99! •  1.000.000,99! •  1 000 000,99!

  49. 4/8/2016!

  50. Is it...! •  April?! •  August?! •  It's my birthday

    – so you're both right!!
  51. Issues! •  Formatting:! •  Numbers change! •  Currencies change! • 

    Dates change! •  UI changes:! •  Buttons! •  Labels! •  Etc!
  52. None
  53. None
  54. Solutions (Formatting)! •  https://www.npmjs.com/package/cordova-plugin-globalization! •  cordova plugin add cordova-plugin-globalization! • 

    Supports numbers, currencies, and dates! •  Supports getting information about locale/language! •  Supports getting information about formats! •  Even supports isDayLightSavingsTime – because that's still a thing apparently!
  55. More Solutions! •  Get some random library! •  Like Moment.js!

    •  http://momentjs.com/docs/#/i18n/!
  56. Even More Solutions! •  Intl! •  ECMAScript Internationalization API! • 

    OMG AWESOME NO PLUGIN NO LIBRARY PERFECT!!!!!!!!!!!!!! 11!!!!! •  Let's check CanIUse.com!
  57. None
  58. None
  59. That other problem...! •  What does "Add to Cart" look

    like in French?! •  Replace buttons/labels/etc with tokens! •  Replace tokens with the right language value!
  60. Resource Bundle! •  Set of key/value pairs! •  Stored by

    language!
  61. { "age": "Age", "email": "Email", "firstname": "First Name", "lastname": "Last

    Name", "register": "Register", "username": "Username" }
  62. { "age": "年年龄", "email": "电⼦子信函", "firstname": "名字", "lastname": "姓", "register":

    "登记", "username": "Username" }
  63. Suggestions! •  https://github.com/doshprompt/angular-localization! •  IBM Globalization (https://ibm.biz/bmglobalize)! •  Demo: http://www.raymondcamden.com/2015/10/14/adding-

    localization-to-your-ionic-application-with-ibm-bluemix/!
  64. Example Code!

  65. navigator.globalization.getLocaleName(function(l) { console.log(l); locale.setLocale(l.value); }, function(err) { console.log('get local err',

    err); });
  66. .value('localeConf', { basePath: 'lang', defaultLocale: 'en-US', sharedDictionary: 'common', fileExtension: '.json',

    persistSelection: false, cookieName: 'COOKIE_LOCALE_LANG', observableAttrs: new RegExp('^data-(?!ng-|i18n)'), delimiter: '::' }).value('localeSupported', [ 'en-US', 'zh-CHS', 'fr-FR' ]);
  67. <label class="item item-input item-stacked-label"> <span class="input-label" data-i18n="app.username"></span> <input type="text"> </label>

  68. User Interface and User Experience

  69. General Tips! •  Test on a real device! •  Use

    native UI as much as possible (dialogs plugin)! •  Use a framework!
  70. None
  71. None
  72. None
  73. Performance! •  Look at what you load over the network!

    •  A secret: JSON isn't always slim (look at the number of rows and the size of each row)! •  Provide instant feedback!
  74. Performance! •  Hardware Accelerated CSS (translate3d)! •  https://www.sitepoint.com/introduction-to-hardware-acceleration- css-animations/!

  75. Performance! •  Use touch vs click! •  300ms! •  Old

    news: Removed in Chrome 32 (for mobile optimized sites)! •  <meta name="viewport" content="width=device-width">! •  Also removed from IE/Edge, FF, and Mobile Safari in iOS9.3!
  76. Performance! •  Minimize DOM thrashing (dom += <b>poo</b> in a

    loop)!
  77. Performance! •  Use the dev tools!! •  https://developers.google.com/web/tools/chrome-devtools/profile/ evaluate-performance/?hl=en! • 

    https://developer.apple.com/library/mac/documentation/ AppleApplications/Conceptual/Safari_Developer_Guide/ Instruments/Instruments.html!
  78. Etc! •  Accessibility! •  https://github.com/phonegap/phonegap-mobile-accessibility! •  Security/Content! •  https://www.raymondcamden.com/2015/03/13/testing-metacerts- security-api-service/!

  79. Wrap Up! •  Contact me at raymondcamden.com! •  Contact me

    at @raymondcamden! •  Share your pain to help others!