Dan Shea
@dancodemonkey
www.dancodemonkey.com
www.positsoftware.com
This talk was inspired by numerous talks at Full Stack Conference, by Skills Matter.
The aim here is to amalgamate those talks into a more succinct presentation aimed at a smaller audience.
I am by no means an expert on this area. I learned some things that were cool, and thought I should share them.
You're on the train...
Inputting fields into a web form
You hit send on this important piece of work...
A wild tunnel appears!
+ More
Sweeping statistics & generalisations
Not all users want an app:
Recent browser features that enable web applications to have a user experience more akin to a native mobile application.
https://codelabs.developers.google.com/codelabs/your-first-pwapp/#2
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', {
scope: '/'
}).then(function (registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function (err) {
console.log('ServiceWorker registration failed: ', err);
});
}
Initialising the Service worker
Register event (site)
Install Event
var cacheName = 'danCodeMonkeyV' + version,
appShellFiles = [
"/",
"/assets/prod/js/all.min.js",
"/assets/prod/css/all.min.css",
"/img/icons/monkey-yellow.svg",
"/img/new-profile.jpg",
"/img/marketsquare.jpg"
],
ignoredUrls = [
"www.google-analytics.com"
];
self.addEventListener('install', function (e) {
e.waitUntil(caches.open(cacheName)
.then(function (cache) {
// Atomic, one fails, it all fails
cache.addAll(appShellFiles);
})
// Older service workers will cause this one to "wait".
// This skips the waiting stage.
.then(self.skipWaiting())
);
});
(App shell initialisation) - (sw)
self.addEventListener('activate', function (e) {
e.waitUntil(caches.keys().then(function (keyList) {
// Flushing the old cache here
return Promise.all(keyList.map(function (key) {
if (key !== cacheName) {
return caches.delete(key);
}
}));
})
.then(function () {
self.clients.claim(); // Force claim all tabs
}));
});
Activate Event (sw)
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(fetchRequest).then(function (response) {
if (!navigator.onLine && response) {
return response;
} else {
return caches.match('/offline');
}
return fetch(fetchRequest).then(function (response) {
return caches.open(cacheName).then(function (cache) {
cache.put(fetchRequest.url, response.clone());
return response;
});
});
});
);
});
Fetch Event
Manifest.json
{
"name": "{{site.title}}",
"icons": [
{
"src": "{{site.baseurl}}{{site.icon-36p}}",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "{{site.baseurl}}{{site.icon-48p}}",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "{{site.baseurl}}{{site.icon-72p}}",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "{{site.baseurl}}{{site.icon-96p}}",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "{{site.baseurl}}{{site.icon-144p}}",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "{{site.baseurl}}{{site.icon-192p}}",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "{{site.url}}",
"display": "standalone",
"background_color": "#000",
"theme_color": "#00cdff"
}
<!-- iOS Web App mode -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Dan Shea">
<link rel="apple-touch-icon" sizes="36x36" href="/img/web-app/icon-36p.png">
<link rel="apple-touch-icon" sizes="48x48" href="/img/web-app/icon-48p.png">
<link rel="apple-touch-icon" sizes="72x72" href="/img/web-app/icon-72p.png">
<link rel="apple-touch-icon" sizes="96x96" href="/img/web-app/icon-96p.png">
<link rel="apple-touch-icon" sizes="144x144" href="/img/web-app/icon-144p.png">
<link rel="apple-touch-icon" sizes="192x192" href="/img/web-app/icon-192p.png">
<!-- Android Web App mode -->
<link rel="manifest" href="/manifest.json">
Add To Head
Web Install Banners
Chrome won't let you decide when to display...
Can defer or cancel the prompt
Alternatively, click/tap the menu, click save to desktop/homescreen
When To Use
function subscribe() {
reg.pushManager.subscribe({ userVisibleOnly: true }) // userVisibleOnly = always show
.then(function (pushSubscription) {
sub = pushSubscription;
SendSubscriptionObjectToServerToStore(sub)
});
}
self.addEventListener('push', function (e) {
e.waitUntil(
self.registration.showNotification('New Blog Post', {
'body': 'A new blog post is up, check it out!',
'icon': 'img/icons/icon144.png'
})
);
});
Push manager - subscribe - (site)
Push event (sw)
Experimental
Was working last time I gave the talk > 1 year a go.
Web Bluetooth
https://jakearchibald.github.io/isserviceworkerready/index.htmlBullet