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

Conquering Mobile with JavaScript (June 2019)

Conquering Mobile with JavaScript (June 2019)

[UPDATED June 2019] Are you looking for a comprehensive mobile development strategy that can help you deliver “the right” mobile app for every project? Look no further. In these workshop slides, we’ll explore a complete workflow for building mobile apps with JavaScript (and TypeScript) that can be applied to any mobile project. From achieving maximum reach with Progressive Web Apps, to delivering maximum richness with native apps powered by JavaScript (via NativeScript), the techniques in this workshop will give you the tools you need to make sure your mobile app projects don’t fail. We'll even explore techniques for sharing code between PWAs and {N} for maximum flexibility.

Ee15d938bcfedc4abeb1fbe520a95ab6?s=128

Todd Anglin

June 10, 2019
Tweet

Transcript

  1. Conquering Mobile with JavaScript PWAs and NativeScript @toddanglin

  2. Todd Anglin Cloud Advocate Lead @ @toddanglin todd.anglin@microsoft.com

  3. None
  4. Agenda PWAs NativeScript Intro Code Sharing AM PM

  5. It's 2019 and we're still talking about how to build

    mobile apps.
  6. What's the problem? Why are you here?

  7. 1. We've built apps, we need a better way 2.

    We're tired of maintaining web AND apps
  8. What we thought. Web Presence Mobile Web Presence iOS app

    Android app Voice skills Chat bots My problem Some else's problem
  9. Reality. Web Presence Mobile Web Presence *Required *Required iOS app

    Android app Preferred for high transaction apps Voice skills Coming soon Chat bots Your problem
  10. Top 3 Problems with "App Strategy v1" 1. Built native

    apps for iOS, Android – too expensive 2. Built hybrid apps – too slow, too janky 3. Built web apps – too limited
  11. None
  12. Reality. Web Presence Mobile Web Presence *Required *Required iOS app

    Android app Preferred for high transaction apps Voice skills Coming soon Chat bots
  13. Okay, okay. But, really. PWA or native app? Which do

    I choose?
  14. None
  15. Common skill set. Shared code. Best of both worlds.

  16. No compromises PWA iOS app Android app Maximum reach, discoverability

    "Light" experience Unlimited power, capability "Premium" experience
  17. Architecture Shared JavaScript/TypeScript Native app stuff Web app stuff Shared

    native UI iOS UI Android UI Web UI
  18. We'll be using JavaScript § It's everywhere § It's the

    web § With TypeScript, it's familiar and easy
  19. Learning Goals for Today 1. Understand PWAs § What are

    they (really)? § How do you get started? § How do you debug? 2. Understand NativeScript § What is it (really)? § How do you get started? § How do you debug? 3. Understand code sharing § What is it? Why do you need it? § How do you get started?
  20. Progress Web Apps (PWAs) The next evolution of the web

  21. What are PWAs (really)? Why do we need them? And,

    what ever happened to Responsive Web Apps?
  22. Evolution of the web Web 1.0 Responsive Web Design Progressive

    Web Apps Foundation Design for all Screens Design for offline
  23. Pillars of PWA 1. Reliable 2. Fast 3. Engaging 1.

    Progressive 2. Responsive 3. Connectivity independent 4. App-like 5. Safe 6. Discoverable 7. Re-engageable 8. Installable 9. Linkable
  24. "Progressive Web Apps use modern web capabilities to deliver an

    app- like user experience." "Progressive Web Apps work everywhere but are supercharged in modern browsers. ."
  25. Common Myths PWAs are a "Google" thing

  26. Common Myths PWAs only work on Android

  27. Common Myths PWAs only make sense on mobile

  28. Common Myths PWAs will replace mobile apps

  29. DEMO Let's look at some PWAs

  30. Works Offline Loads Fast "App-like"

  31. Service Workers web app manifest "App-like"

  32. Application Shell My App My App Settings Account Something else

    My App 80º Orlando 20º Boston Shell Content Cached on first visit Loaded from network
  33. Approaches to PWA 1. App Shell + Server-Side Render (SSR)

    for Entry Pages 2. App Shell + Client-Side Render (CSR) for Content 3. Full SSR SSR == Server-Side Rendering
  34. PWA "minimum requirements" HTTPS Service Worker Web App Manifest

  35. Image source: "Your First Progressive Web App", Google Developers •

    App shell method • Make it work offline • Using Angular
  36. Demo Create baseline Angular Weather App

  37. Lighthouse • Check PWA readiness • Detect common problems •

    Audit performance
  38. Demo Lighthouse

  39. Service Worker § It's just a separate JavaScript file §

    Special type of web worker focused on controlling network requests § Runs separate from main thread § Can run in the background (when no tab open) § No direct DOM access § Communicates with main thread via postMessages § One service worker "per scope" § Updated (at least) every 24 hours
  40. Service Worker Server Your page Service Worker GET request HTTPS

    Cache Browser
  41. Service Worker Server Your page GET request HTTPS Older Browser

    if ('serviceworker' in navigator)
  42. None
  43. Service Worker fetch cache API for retrieving content from the

    network API for storing/retrieving cached app content/data
  44. None
  45. Service Worker Lifecycle First Install 1. register 2. install 3.

    activate 4. idle Updates 1. install 2. waiting 3. activate 4. idle navigator.serviceWorker.register('./service-worker.js')
  46. DEMO Starting our PWA with a Service Worker

  47. Caching

  48. Cache strategies § Cache Only § Network Only § Cache

    First, Fallback on Network § Cache First, Then Network § Cache and Network Race § Network First, Fallback on Cache § Generic Fallback
  49. Cache Only For "static" resources that change with "versions" of

    your site Page Cache Service Worker 1 2 3
  50. Network Only For resources that cannot (or should not) be

    cached Page Network Service Worker 1 2 3
  51. Cache First, Fallback on Network Primary offline-first pattern: load from

    cache if available, otherwise fetch Page Cache Service Worker Network x 1 2 3 4
  52. Network First, Fallback on Cache Load new content by default,

    or show cache if offline Page Cache Service Worker Network x 1 2 3 4
  53. Cache First, Then Network Display cached resource immediately, then update

    when network responds Page Cache Service Worker Network 1 1 2 2 3
  54. Cache and Network Race For cases where disk access may

    be slower than network response Page Cache Service Worker Network 1 2 2 3 x 3
  55. Generic Fallback For stuff that's not available in the cache

    OR on the network Page Cache Service Worker Network 1 2 3 x 5 x 4
  56. None
  57. Offline Fallback Page

  58. § JavaScript library to handle service worker boilerplate workbox.routing.registerRoute( new

    RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'), workbox.strategies.cacheFirst(), ); workbox.routing.registerRoute( /\.(?:js|css)$/, workbox.strategies.staleWhileRevalidate(), );
  59. § PWA schematic automatically creates and manages service worker $

    ng add @angular/pwa --project *project-name* $ ng build --prod
  60. ngsw-config.json assetGroups § Static resources versioned with your app §

    App shell, images, styles, etc § installMode/updateMode § lazy § prefetch dataGroups § Caching policy for resources not versioned with your app § API responses § cacheConfig § maxSize (# of entries) § maxAge § timeout § strategy § performance § freshness
  61. DEMO Using Angular PWA

  62. Web App Manifest § Evolution of mobile meta tags §

    Control PWA's home screen icon, splash screen, theme colors, start URL § Helps PWA feel more "app like" (on Android) <link rel="manifest" href="/manifest.json">
  63. Image Source: Addy Osmani, https://addyosmani.com/blog/getting-started-with-progressive-web-apps/ Web App Install banner Requires:

    • Web App Manifest • HTTPS • Registered Service Worker • “Engagement heuristic” • 2 visits, at least 5 min between visits • 30 seconds “interacting” with domain
  64. Install Prompt § Events: § beforeinstallprompt § appinstalled Opportunity to

    intercept browser install banner and control when it is displayed
  65. Image Source: Addy Osmani, https://addyosmani.com/blog/getting-started-with-progressive-web-apps/ Home screen icon & splash

    screen Define: • App icon • App name • App theme color • Splash screen background color • Orientation limits
  66. None
  67. • name • short_name • icons • dir • lang

    Control Home Screen • start_url • display • fullscreen, standalone, minimal-ui, browser • orientation • any, natural, landscape, portrait, landscape-preferred, landscape-secondary, portrait- preferred, portrait-secondary • background_color • theme_color Control App Behavior • description • related_ applications • prefer_ related_ applications • scope Extras
  68. DEMO Adding web app manifest

  69. Hosting § Azure for Static Sites § Uses Azure Storage

    § SUPER simple with VS Code § PWA friendly Azure account VS Code Azure Storage Plugin
  70. DEMO Publishing static site to Azure

  71. PWA Frameworks ReactPWA Angular CLI (!) vue-pwa-boilerplate Polymer App Toolbox

    Kendo UI Ionic
  72. Migrating an Existing Site § It's possible! § Best to

    start with a SPA architecture
  73. Additional Web APIs § Background Sync § Payment Request API

    § Web Push Notifications § Web VR
  74. Background Sync // Register your service worker: navigator.serviceWorker.register('/sw.js'); // Then

    later, request a one-off sync: navigator.serviceWorker.ready.then(function(swRegistration) { return swRegistration.sync.register('myFirstSync'); }); self.addEventListener('sync', function(event) { if (event.tag == 'myFirstSync') { event.waitUntil(doSomeStuff()); } }); In app js: In service worker:
  75. None
  76. None
  77. None
  78. Apple Pay JS Image source: https://developers.bluesnap.com/docs/apple-pay

  79. [2] Requires full browser to be running to receive messages

    [3] Apple has custom API for desktop Safari
  80. PWA All the things?

  81. PWA Limits Safari Older Browsers Native APIs

  82. iOS & Safari § Some PWA features coming soon §

    BUT some potentially problematic differences
  83. Notable limits on iOS § Limited to 50 MB (files

    and data) § No background sync (or background execution) § No ability to lock screen orientation § No app splash screen* § No “installation” UX § Less control over status bar styling § PWAs ”restart” every time the user switches apps § PWAs don’t work in non-default iOS browsers (Chrome, Brave, etc) § Auto-purged PWA cache for infrequently used apps
  84. None
  85. When to PWA § Content centric apps § Read only

    OR apps with simple inputs § No user expectation of App Store install § No need for extensive device hardware access § Less need for on device encryption, storage
  86. All web apps should implement PWA for a better web.

    (But you may still want a native mobile app.)
  87. LUNCH Resume @ 1:00 PM

  88. Download the NativeScript Playground & Preview apps PWA Weather App

    Source: https://github.com/toddanglin/NsPwaWeather While you wait…
  89. NativeScript Native mobile apps with JavaScript

  90. Hybrid (& PWA) Promise 100% Web 100% Native Hybrid Reach

    Code/Skill Reuse Richness Premium experience Device APIs Best of both?
  91. Binary Choice Native Hybrid Fast to market Best experience

  92. JavaScript- driven native Fast to market Best experience

  93. "PWA" Offline-enabled web apps with access to browser APIs Browser

    WebView Entire app lives here
  94. "Hybrid" Web UI with selective access to native APIs Native

    App Shell WebView Plugins Plugins Entire app lives here
  95. Native App "JavaScript-driven Native" Native UI driven by JavaScript Native

    UI JavaScript-to-Native bridge JavaScript Engine (Your app code runs here) Native APIs
  96. NativeScript (by Progress) React Native (by Facebook) “JavaScript-driven Native”

  97. “JavaScript-driven Native” • Share code • Reuse existing skills/teams •

    Reuse existing libraries • Native UI • Full access to device APIs • Immediate access to new OS features Fast to market Best experience
  98. • Open source • Cross-platform • JavaScript/TypeScript • Native iOS

    & Android UI Reuse web skills and libraries to build better mobile apps
  99. SKILLS & FRAMEWORKS TOOLS LIBRARIES

  100. Building a {N} app <page> <stacklayout> <label id=“myLbl” text=“Hello World”>

    </label> </stacklayout> </page> 1) Layout views 2) Style with CSS Page { background-color: #333; color: #000; padding: 10; } 3) Control with JS submit() { alert(“You did it!”); } Deploy native apps to iOS and Android
  101. 2015 2016 2017 2018 v1 v2 v3 v4 NativeScript Journey

    v5
  102. Monthly NPM Downloads 100k 200k • Over 4.2 million downloads

    • 2x increase YoY in 2018 (130%)
  103. React Native NativeScript MONTHLY NPM CLI DOWNLOADS

  104. React Native NativeScript

  105. 0% 50% 100% Sep '17 Oct '17 Nov '17 Dec

    '17 Jan '18 Feb '18 Mar '18 Apr '18 May '18 Jun '18 Jul '18 Aug '18 Sep '18 Oct '18 Nov '18 Dec '18 Jan '19 Feb '19 CLI Template Usage Angular Pure JavaScript Pure TypeScript Vue.js
  106. None
  107. MYPUMA puts wholesale fashion in the pocket of buyers and

    allows them to purchase PUMA's latest styles anywhere, anytime. NativeScript enables premium app experiences and easy access to iOS and Android users.
  108. Get Started

  109. None
  110. Starting a new project (CLI) $ npm install –g nativescript

    $ tns create MyFirstProject --ng $ tns preview
  111. Instantly start developing with {N} in a browser • Fastest

    way to get started with {N} • Support for Angular and Vue
  112. None
  113. Demo Playground & Preview

  114. How does NativeScript work? Under the covers

  115. None
  116. Generated at build time for OS & 3rd party native

    libraries
  117. NativeScript Android example output: JavaScript

  118. NativeScript iOS example JavaScript

  119. None
  120. Runs on V8 JavaScript VM Runs on JavaScriptCore VM

  121. None
  122. NativeScript Module Layer (NML) § Abstractions on native APIs that

    provide unified, cross- platform API § Dozens available out of the box § Easy for developers to add § IMPORTANT: All native APIs still available at JavaScript layer for platform- specific scenarios § NativeScript modules follow Node module’s conventions (CommonJS).
  123. Example: NativeScript file module

  124. None
  125. AR/VR Support • Support for ARKit and ARCore • Support

    for iOS vector type • Image Tracking and Face Tracking (iOS) • Load 3D models • Interact with planes
  126. Image source: "Your First Progressive Web App", Google Developers •

    App shell method • Make it work offline • Using Angular
  127. Defining Views

  128. Pages § XML markup structure § Elements (e.g. <Page>, <Label>)

    are NativeScript modules Angular Gotcha Must use closing tags with Angular
  129. Layouts UI Elements

  130. Layouts Absolute Dock Grid Stack Wrap

  131. None
  132. Layouts: FlexBox <div style="display: flex;"> </div> == These are the

    same == <FlexboxLayout> </FlexboxLayout> Supported Flex properties: § Set flex properties via XML, CSS or JS § Uses same syntax as web § Use FlexboxLayout as root element § Same as HTML <div /> with "display: flex;" § Multiple FlexboxLayouts can be nested For containers: • flex-direction • flex-wrap • flex-flow • justify-content • align-items • align-content For children: • order • flex-grow • flex-shrink • flex • align-self • flex-wrap-before
  133. UI Widgets § Button § Label § TextField § TextView

    § SearchBar § Switch § Slider § Progress § ActivityIndicator § Image § ListView § HtmlView § WebView § TabView § SegmentedBar § DatePicker § TimePicker § ListPicker § Dialogs Out-of-the-box Native UI widgets means… • Native behavior • Native perf • Native accessibility • Parity with “native”
  134. Native UI widgets Native API {N} Module button android.widget.Button UIButton

  135. NativeScript UI (free) • ListView • SideDrawer • Calendar •

    Chart • DataForm • Gauges • AutoComplete
  136. ActionBar Layout + UI

  137. 3 rows 3 columns

  138. Demo

  139. Basic Styling with CSS

  140. CSS Convention: app.css <-- Global styles [viewName].css <-- View styles

    [viewName].[platform].css @Component({ ... styleUrls: ["./items.component.css"] })
  141. Supported Properties § color § background-color § background-image § background-repeat

    § background-position § background-size § border-color § border-width § border-radius § font § font-family § font-size § font-style § font-weight § text-align § text-decoration § text-transform § vertical-align § horizontal-align § margin § margin-top § margin-right § margin-bottom § margin-left § width § height § min-width § min-height § padding § padding-top § padding-right § padding-bottom § padding-left § visibility § opacity
  142. Supported Selectors § Element § button { color: red; }

    § Class § .mybutton { color: green; } § ID § #myButton { color: #FFF; } § Hierarchical § button .mybutton { … } § button > .mybutton { … } § Attribute § button[attr] { … } § button[attr='val'] { … } § Pseudo § button:highlighted { … }
  143. Sass § Use Sass syntax § Auto-compiled $ tns install

    sass
  144. Theme

  145. Theme Core § Bootstrap for {N} § Pre-defined CSS classes

    to quickly give apps a polished look-and-feel § iOS and Android $ npm install nativescript-theme --save
  146. Theme for text <Label text="Name" class="text- primary text-right"></Label> <Label text="Email"

    class="text- danger"></Label> Change text color: - text-primary, text- muted, text-danger Change text alignment: - text-center, text- left, text-right to Apply text transformation - text-lowercase, text- uppercase, text-capitalize
  147. Theme for buttons <Button text="Primary" class="btn btn- primary"></Button> <Button text="Outline"

    class="btn btn- outline"></Button> <Button text="Orange" class="btn btn-primary btn- ornage"></Button> <Button text="Rounded Grey" class="btn btn-primary btn-grey btn-rounded- sm"></Button>
  148. Theme BEFORE AFTER

  149. Demo Theme and styling

  150. Custom Fonts 1. Use TTF or OTF fonts 2. Put

    fonts in: app > fonts 3. Use in CSS .icon { font-size: 30; font-family: 'FontAwesome'; }
  151. Icon Font Helper § Angular pipe for handling icon fonts

    <Label class="fa" text="\uf293"></Label> <Label class="fa" [text]="'fa-bluetooth' | fonticon"></Label> npm install nativescript-ngx-fonticon --save
  152. Pipes § Transform bound data import { Pipe, PipeTransform }

    from "@angular/core"; @Pipe({ name: "myPipeName" }) export class MyPipe implements PipeTransform { transform(value: number): any { // Do something return newValue; } }
  153. TIP § Platform specific capabilities are always available § JavaScript:

    <view>.android or <view>.ios § Markup: <android></android> or <ios></ios> § Attributes: android:<attribute> or ios:<attribute> § Ex: <label android:class="…" ios:class="…" /> Write once by default. Target specific platform capabilities when needed.
  154. Integrations & Ecosystem

  155. Plugin Ecosystem

  156. NativeScript Marketplace

  157. Android iOS Webpack Has Demo Has Docs {N} 3.x {N}

    4.x Typings CI Builds Popular
  158. Expanding Templates Enterprise Auth Template (Kinvey)

  159. None
  160. Basic Data Binding with Angular

  161. [ value ] or {{ value }} = One way

    binding from class to view
  162. import { Component } from ”@angular/core” @Component({ selector: 'app', template:

    ` <input value=”{{ message }}”> ` }); export class AppComponent { message: 'Root Component' } app.component.ts
  163. [(ngModel)] = Two way binding

  164. import { Component } from ”@angular/core” @Component({ selector: 'app', template:

    ` <input [(ngModel)]=”message”> <button (click)=“showMessage()”>Show Message</button> ` }); export class AppComponent { message: 'Root Component’; showMessage() { alert(this.message); } } app.component.ts
  165. Two-way binding import { NativeScriptFormsModule } from 'natives cript-angular/forms'; …

    imports: [ NativeScriptModule, AppRoutingModule, NativeScriptHttpModule, NativeScriptFormsModule ], § You also need to add NativeScriptForms Module to @NgModule imports
  166. ( event ) = Binds an event to a function

  167. import { Component } from ”@angular/core” @Component({ selector: 'app', template:

    ` <label [text]=”message”> <button (tap)=“showMessage($event)”>Show Message</button> ` }); export class AppComponent { message: 'Root Component’; showMessage() { alert(this.message); } } app.component.ts
  168. Events <Label text="Action:" (swipe)="printDirection($event)"> </Label> § If event provides parameters,

    then add $event
  169. Handling Events tap label.on(gestures.GestureTypes.tap, function (args) { console.log("Tap"); }); swipe

    label.on(gestures.GestureTypes.swipe, function (args) { console.log("Swipe Direction: " + args.direction); }); Multiple events label.on("tap, doubleTap, longPress", function (args) { console.log("Event: " + args.eventName); }); § Tap § Double Tap § Long Press § Swipe § Pan § Pinch § Rotation § Touch
  170. Demo Data binding

  171. Services And Injection

  172. export class MessageService { message: string = ”Service Message” }

    message.service.ts
  173. import { Injectable } from ”@angular/core” export class MessageService {

    message: string = ”Service Message” } message.service.ts
  174. import { Injectable } from ”@angular/core” @Injectable() export class MessageService

    { message: string = ”Service Message” } message.service.ts
  175. import { Component } from ”@angular/core” @Component({ selector: 'app', template:

    ` <input [(ngModel)]=”message”> <button (click)=“showMessage()”>Show Message</button> ` }); export class AppComponent { message: 'Root Component’; showMessage() { alert(this.message); } } app.component.ts
  176. import { Component } from ”@angular/core” import { MessageService }

    from ”./message.service” @Component({ selector: 'app', template: ` <input [(ngModel)]=”message”> <button (click)=“showMessage()”>Show Message</button> ` }); export class AppComponent { message: 'Root Component’; showMessage() { alert(this.message); } } app.component.ts
  177. @Component({ selector: 'app', providers: [MessageService] template: ` <input [(ngModel)]=”message”> <button

    (click)=“showMessage()”>Show Message</button> ` }); export class AppComponent { message: string; showMessage() { alert(this.message); } constructor(MessageService _messageService) { this.message = _messageService.message; } app.component.ts
  178. Debugging

  179. “If debugging is the process of removing software bugs, then

    programming must be the process of putting them in.” - Edsger Dijkstra
  180. Debugging Strategies § Debug by alert (no really) § Debug

    by console.log § Debug by Developer Tools § Debug by IDE § Visual Studio § Visual Studio Code
  181. What are your favorite web debugging tools?

  182. Chrome Dev Tools Sources

  183. Chrome Dev Tools Memory

  184. Chrome Dev Tools Network

  185. Chrome Dev Tools Elements

  186. Demo Debugging

  187. Web + Mobile Code Sharing • Build for web and

    mobile in one project • Leverages Angular schematics • Share business logic, routing
  188. Sharing DO share: - Routes - Services - Component definitions

    (common behavior) - (Some) Styles DON’T share: - UI layer - NgModules
  189. None
  190. Components

  191. Modules

  192. Additional Code Sharing *.common.ts *.module.ts *.module.tns.ts

  193. Code Splitting Strategies Polyfills • Make web APIs work in

    {N} Helpers • Inject services to handle specific functions differently for web & {N} Separate files • Create separate files for web & {N}
  194. Pre-reqs § Angular CLI § NativeScript CLI § @nativescript/schematics

  195. Options § Start with a new project § Convert an

    existing Angular web project § Convert an existing {N} project (coming soon) $ ng add @nativescript/schematics $ ng g migrate-module --name=home $ ng new -c=@nativescript/schematics project-name --shared Migrate New
  196. Demo Migrate Weather App to Code Sharing

  197. Why do this? § Improve developer workflow across web, mobile

    § Share more code/assets between web, mobile § Deliver web, mobile updates simultaneously
  198. Wrap-up

  199. NativeScript for Angular Mobile Development Available on Packt by Nathan

    Walker & Nathanael Anderson
  200. The NativeScript Book Available. for FREE. by The Brosteins nativescript.org/book

  201. nativescripting.com

  202. Building Progressive Web Apps Tal Ater

  203. No compromises PWA iOS app Android app Maximum reach, discoverability

    "Light" experience Unlimited power, capability "Premium" experience +
  204. Architecture Shared JavaScript/TypeScript Native app stuff Web app stuff Shared

    native UI iOS UI Android UI Web UI
  205. When should you add PWA? When should add {N}?

  206. • Largely read-only • Simple user interactions • Mostly dynamic

    content • No need to access device APIs • No need for encrypted device storage • Web distribution • Frequently used • More complex user interactions • Need for access to device APIs • Need for encrypted storage • App store distribution PWA
  207. Thanks! @toddanglin todd.anglin@Microsoft.com