Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Building Progressive Web Apps for Windows devices

2,191 views

Published on


In this session, you'll learn what's in store for Progressive Web Apps on Window - where they fit in alongside other Windows apps; how to get started converting a web site or web app into a Progressive Web App; how to submit PWAs to the Windows Store , and more.

Published in: Technology
  • If you want to enjoy the Good Life: making money in the comfort of your own home with just your laptop, then this is for YOU... ★★★ http://ishbv.com/goldops777/pdf
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • The Odds of The Lotto Are Changing With These Tricks!  http://t.cn/Airfq84N
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • TEENS ARE LOOKING FOR REAL SEX NEAR YOU! HOOK-UP TONIGHT! ♣♣♣ http://t.cn/AiuWKDWR
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Penis Enlargement and Enhancement Techniques: What REALLY Works?!? ★★★ https://bit.ly/30G1ZO1
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • I went from getting $3 surveys to $500 surveys every day!! learn more... ♥♥♥ https://tinyurl.com/realmoneystreams2019
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Building Progressive Web Apps for Windows devices

  1. 1. A PWA is Progressive Works on any device and enhance functionality progressively. Discoverable Better discovery and integration with search. Linkable Ability to retain or reload its state and be shareable from a link. Responsive Fit any device’s form factor and screen size. App-like Looks like a native app and uses the application shell model with minimal page refreshes. Connectivity-agnostic Works with low connectivity or offline. Installable Install on the device’s desktop, start menu, or task bar making it readily available. Current Application and content is up to date when connected to the Internet. Re-engageable Promotes re-engagement through features such as push notifications. Performant Works as fast or faster than a native app. Connected to users Direct feedback to you through ratings and reviews
  2. 2. Why PWA? Our Goal: The very best experience for your Web content will be on Windows
  3. 3. Keep your workflow for web Build Deploy Publish App Web Content Build Build with web technology and web developers. No need to find and hire c# developers. Deploy The work flow for web and PWAs are shared, so your deploy process doesn’t need to change to accommodate PWA. Publish App Your PWA “app container” needs only to be published once. The content is always up to date because it comes from the web. Web The same app runs across browsers and can take advantage of PWA features as needed / supported. PWA The same app serve as a store app with even more features and additional reach to store users.
  4. 4. Devices + IoT Mobile PC Xbox Surface Hub HoloLens A C R O S S W I N D O W S C R O S S P L AT F O R M PROGRESSI VE WEB APPS X
  5. 5. HTTPS Web App Manifest Service Worker Minimum Viable Progressive Web App
  6. 6. Web Application Manifest { "lang": "en", "short_name": "Wash Post", "name": "The Washington Post", "icons": [ { "src": "img/launcher-icon-2x.png", "sizes": "96x96", "type": "image/png" }, { "src": "img/launcher-icon-4x.png", "sizes": ”512x512", "type": "image/png" } ], "start_url": "/pwa/?utm_source=homescreen", "display": "standalone", "orientation": "portrait", "background_color": "black" }
  7. 7. Web Application Manifest { "lang": "en", "short_name": "Wash Post", "name": "The Washington Post", "icons": [ { "src": "img/launcher-icon-2x.png", "sizes": "96x96", "type": "image/png" }, { "src": "img/launcher-icon-4x.png", "sizes": ”512x512", "type": "image/png" } ], "start_url": "/pwa/?utm_source=homescreen", "display": "standalone", "orientation": "portrait", "background_color": "black" }
  8. 8. Web Application Manifest { "lang": "en", "short_name": "Wash Post", "name": "The Washington Post", "icons": [ { "src": "img/launcher-icon-2x.png", "sizes": "96x96", "type": "image/png" }, { "src": "img/launcher-icon-4x.png", "sizes": ”512x512", "type": "image/png" } ], "start_url": "/pwa/?utm_source=homescreen", "display": "standalone", "orientation": "portrait", "background_color": "black" }
  9. 9. Web Application Manifest { "lang": "en", "short_name": "Wash Post", "name": "The Washington Post", "icons": [ { "src": "img/launcher-icon-2x.png", "sizes": "96x96", "type": "image/png" }, { "src": "img/launcher-icon-4x.png", "sizes": ”512x512", "type": "image/png" } ], "start_url": "/pwa/?utm_source=homescreen", "display": "standalone", "orientation": "portrait", "background_color": "black" }
  10. 10. App display Property • Runs in Edge as a separate windows or Tab. • Full browser UI, no store listing Browser • Runs in App container in separate process. • No browser UI, back button only. • Microsoft store listing Standalone UI • Runs in App container in separate process. • Limited UI (navigation & read only nav bar). • Microsoft store listing Minimal UI
  11. 11. Network request: Typical Web App Network
  12. 12. Network request: Service Worker in play Web App Service Worker Network Cache
  13. 13. if ( navigator.serviceWorker ) { if ( navigator.serviceWorker.controller ) { console.log('There’s an active service worker'); } else { navigator.serviceWorker.register('/sw.js') .then(function(reg) { console.log('SW registered for scope', reg.scope); }); } }
  14. 14. if ( navigator.serviceWorker ) { if ( navigator.serviceWorker.controller ) { console.log('There’s an active service worker'); } else { navigator.serviceWorker.register('/sw.js') .then(function(reg) { console.log('SW registered for scope', reg.scope); }); } } This tests to see if Service Workers are supported.
  15. 15. if ( navigator.serviceWorker ) { if ( navigator.serviceWorker.controller ) { console.log('There’s an active service worker'); } else { navigator.serviceWorker.register('/sw.js') .then(function(reg) { console.log('SW registered for scope', reg.scope); }); } } We can also see if there’s a Service Worker already running.
  16. 16. if ( navigator.serviceWorker ) { if ( navigator.serviceWorker.controller ) { console.log('There’s an active service worker'); } else { navigator.serviceWorker.register('/sw.js') .then(function(reg) { console.log('SW registered for scope', reg.scope); }); } } If there isn’t, we can register one.
  17. 17. if ( navigator.serviceWorker ) { if ( navigator.serviceWorker.controller ) { console.log('There’s an active service worker'); } else { navigator.serviceWorker.register('/sw.js') .then(function(reg) { console.log('SW registered for scope', reg.scope); }); } } By default, a Service Worker is scoped to its path.
  18. 18. addEventListener('fetch', function(evt) { evt.respondWith( fromCache(evt.request) .catch(fromServer(evt.request))); evt.waitUntil(update(evt.request)); });
  19. 19. addEventListener('fetch', function(evt) { evt.respondWith( fromCache(evt.request) .catch(fromServer(evt.request))); evt.waitUntil(update(evt.request)); }); In a Service Worker we can intercept any network requests (“fetch”).
  20. 20. addEventListener('fetch', function(evt) { evt.respondWith( fromCache(evt.request) .catch(fromServer(evt.request))); evt.waitUntil(update(evt.request)); }); And we can control the response. In this case responding from the cache first.
  21. 21. addEventListener('fetch', function(evt) { evt.respondWith( fromCache(evt.request) .catch(fromServer(evt.request))); evt.waitUntil(update(evt.request)); }); If no cached response is found, we can go to the network.
  22. 22. addEventListener('fetch', function(evt) { evt.respondWith( fromCache(evt.request) .catch(fromServer(evt.request))); evt.waitUntil(update(evt.request)); }); We can also update the cache for the next time the request is made.
  23. 23.  Validate your PWA is ready for Microsoft Store  Improve perf and User Experience
  24. 24. https://sonarwhal.com/scanner/e2da8548- 6afe-4944-a736-dd3c286e2a87
  25. 25. dev.microsoft.com reportapp@microsoft.com
  26. 26. PWABuilder.com
  27. 27. Value Add of Windows Store App
  28. 28. // Am I installed in Windows? if ( window.Windows ){ // pin a secondary tile tile = new Windows.UI.StartScreen.SecondaryTile(tileId, text, text, activationArguments,newTileDesiredSize, logoUri); //place activation var buttonCoordinates = { x: SR.left, y: SR.top, width: SR.width, height: SR.height }; var placement = Windows.UI.Popups.Placement.above; } Access OS-level APIs Secondary Pinning
  29. 29. PWA Activation Object Windows.UI.WebUI.WebUIApplication.addEventListener('activated', function(args) { if (args.kind === Windows.ApplicationModel.Activation.ActivationKind.voiceCommand) { var results = args.result, spoken = results.text, command = results.rulePath[0], details, redirect; if (command === 'open') { details = results.semanticInterpretation.properties.section[0]; switch (details) { case "watchlist": redirect = "https://www.mydomain.com/user/watchlist"; break; case “login": redirect = "https://www.mydomain.com/user/login"; break; … } }
  30. 30. 1 2 3 Getting Started Configuration APIs Feature APIs Agenda
  31. 31. 46 Section Creating the Windows App PWABuilder.com Changed logos Edited version info Uploaded + Submitted as Beta Integration testing VirtualBox + VM, Charles Proxy to https://localhost.twitter.com (via hosts file change, helps with HTTPS + CSP) Dev Tools Preview Edition Manually install/sideload to debug
  32. 32. 47 Section The Hard Parts -API is massive! -Lack / inaccuracy of JS documentation and examples - Learn how to translate from C# (Class.Prop -> Class.prop) - Hard to figure out the effect of certain calls from docs (e.g. review request) -Boilerplate/config often imperative instead of config based -ASync is not native JS Promises--cannot Promise.all() - Can however just .then everything
  33. 33. 48 Section Configuration APIs / Core Path Things that interact with Windows by setting or getting variables May want them in the core render path, e.g. not code-split Usually not async => no promises!
  34. 34. DO THIS FIRST // This must not be deferred so that it can receive the initial 'activated' event in time window.Windows.UI.WebUI.WebUIApplication.addEventListener( 'activated', e => microsoftInterfaceLoader().then(microsoftInterface => { microsoftInterface.handleActivatedEvent(e); }), false ); // Without this, the app will first refresh to the start path before every activate event window.MSApp.pageHandlesAllApplicationActivations(true);
  35. 35. 50 Read / Set Up Window
  36. 36. 51 Read / Set Up Window
  37. 37. 52 Read / Set Up Window const currentView = window.Windows.UI.ViewManagement.ApplicationView.getForCurrentView(); // Sometimes we were getting stuck in fullscreen mode because // the user had closed the app with a video open currentView.isFullScreenMode && currentView.exitFullScreenMode(); // 325px is a safe minimum size that allows the tweet layout to look OK currentView.setPreferredMinSize({ width: 325, height: 400 });
  38. 38. 53 Read / Set Up Window
  39. 39. const isWindowsDarkMode = () => { const uiSettings = new window.Windows.UI.ViewManagement.UISettings(); const color = uiSettings.getColorValue( window.Windows.UI.ViewManagement.UIColorType.background ); return color.r === 0 && color.g === 0 && color.b === 0; }; // Prefer cookie setting, fallback to WinPWA if not set const cookies = canUseDOM ? cookie.parse(document.cookie) : {}; const cookieNightModeOn = cookies[NIGHT_MODE_COOKIE] === '1'; const windowsNightModeOn = isWindowsPwa && cookies[NIGHT_MODE_COOKIE] === undefined && isWindowsDarkMode(); (cookieNightModeOn || windowsNightModeOn) && StyleSheet.setTheme('dark'); Read / Set Up Window
  40. 40. 55 Section Feature APIs Twitter Windows APIs PasswordVault Share Integration** Notifications Pinning Jump Links **(for images) Store reviews / Feedback Timeline Protocol Handling **
  41. 41. 56 Section Feature APIs
  42. 42. // Set a default interface so elsewhere in our code we don’t have to care // what happens, we can just call this.context.hostInterface.visitedMomet let hostInterface = { onPostLoad: noop, pinnedUser: noop, visitedMoment: noop, } // If we are on Windows...load the interface for that host system... // Now some functions may be defined and actually do things! isWindowsPWA && microsoftInterfaceLoader().then(microsoftInterface => { hostInterface = { ...hostInterface, microsoftInterface } }); Code Split
  43. 43. Share! window.navigator.share = ({ text, title, url }): Promise => ???
  44. 44. let shareData = {}; // On the windows api event, we then reattach it and format it const handleShareEvent = e => { const { text, title, url } = shareData; const request = e.request; request.data.properties.title = title; request.data.properties.description = text; const uri = new window.Windows.Foundation.Uri(url); request.data.setWebLink(uri); }; ShareShim.js
  45. 45. ... microsoftInterface.onPostLoad = () => { if (window.navigator.share) { return; } // It’s a Polyfill const dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView(); dataTransferManager.addEventListener('datarequested', handleShareEvent); // Windows interface means we trigger an event and then immediately consume it // store the data here, for the event handler above to use window.navigator.share = currentShareData => { shareData = currentShareData; window.Windows.ApplicationModel.DataTransfer.DataTransferManager.showShareUI(); return Promise.resolve(); }; }; ShareShim.js
  46. 46. Calling C# from a webview namespace CommunicationWinRT { [Windows.Foundation.Metadata.AllowForWeb] public sealed class CommunicationWinRT { public CommunicationWinRT() { } public String GetValue() { return "From my WinRT component Yo!"; } } }
  47. 47. Calling C# from a webview document.getElementById('toast').addEventListener('click', function () { if (window.CommunicationWinRT) { testToast.toastMessage(document.getElementById('input').value, 0) } else { alert(document.getElementById('input').value) } }) if (window.CommunicationWinRT) { var testToast = new CommunicationWinRT.CommunicationWinRT(); }
  48. 48. Capabilities UserExperience
  49. 49. Service Worker calling WinRT APIs addEventListener('fetch', function(evt) { evt.respondWith( fromCache(evt.request) .catch(fromServer(evt.request))); evt.waitUntil(function(evt.request){ Windows.Storage.AccessCache.StorageApplicationPermissions .futureAccessList.add(evt.request); }); });
  50. 50. Remember 1. PWAs are part of Windows to enable Web developers to build great user experiences. 2. PWAs can naturally or specifically be added to the Microsoft store. 3. PWAs are powerful, flexible and extensible on Windows. 4. We’re not done yet!

×