HTML5 offline app using Service Worker

How can I make an offline app for ios using Service Worker?

I never used Service Worker so I don’t know how difficult it can be to use it with OpenFL.

1 Like

I’ve added a Service Worker ability to my app. The cache seems to work independently so all my assets are loaded from the cache by the Service Worker but OpenFL try to load the assets independently so the preloader is stuck and never finished :frowning:

How can I tell OpenFL to load from the cache?

EDIT: hum, seems to work now. Just have to launch twice the app to make the cache installation process complete before using the app offline. But videos in my app are not displayed.

Let me know if there’s anything you find that we can use to make OpenFL work better in this use-case, or even enable this out-of-the-box

Hello, thanks for your feedback.

Indeed, OpenFL could be able to automate some things:

  1. Add a compiler option : -Dhtml5-offline ?
  2. Add 2 javascript files before any others in the html template, add them also in the bin folder at the same place as the index.html.

The first one registers the Service Worker.

service_worker_register.js

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('./service_worker.js').then(function(registration) {
    
    console.log('ServiceWorker registration successful with scope: ',    registration.scope);
  }).catch(function(err) {
    console.log('ServiceWorker registration failed: ', err);
  });
}

The second is the Service Worker. OpenFL could list all resources here.

service_worker.js

'use strict'

const CACHE_NAME = 'cache';

const resourceList = [
  '/',
  'index.html',
  'favicon.png',
  'fonts/fonts.eot',
  'fonts/fonts.otf',
  'fonts/fonts.woff',
  'lib/FileSaver.min.js',
  'lib/howler.min.js',
  'lib/pako.min.js',
 ...
  'manifest/default.json',
  'OpenFL.js'
];

self.addEventListener('install', event => {
  event.waitUntil(caches.open(CACHE_NAME).then(cache => {
    return cache.addAll(resourceList);
  }));
});

function addToCache(cacheName, resourceList) {
  caches.open(cacheName).then(cache => {
    return cache.addAll(resourceList);
  });
}

self.addEventListener('fetch', event => {
  event.respondWith(caches.match(event.request).then(response => {
    return response || fetch(event.request);
  }));
});
  1. Add a manifest.json in the bin folder (same place as index.html)
{
  "short_name": "::APP_TITLE::",
  "name": "::APP_TITLE::",
  "icons": [
    {
      "src": "/favicon.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "display": "standalone",
  "background_color": "#000000",
  "orientation": "landscape"
}

I have templates for the HTML (icons and metatags filled), service worker.js (asset lists and cache version based on app version), and manifest.json. Also some modifications to the openfl/lime exporter to support a -pwa flag.

I will share them when I get home. My problem is that the asset list I got has the original names and openfl/lime append a query to all assets to prevent an old version for being cached and is that what breaks my service worker.

The query should be per build, not per run of the application, so it should still work offline after making the build, if I’m not misunderstanding?

2 solutions:

  1. You can force the suffix number in the query like that: <haxedef name="lime-assets-version" value="100" /> and add this to your list of cached assets in your service worker.
  2. You can remove ? and the number in the request before querying the service worker cache