Как обновить sh кеш для PWA на iOS? - PullRequest
0 голосов
/ 26 марта 2020

Я делаю свои первые шаги с PWA и пытаюсь заставить работать стратегию кэширования на iOS устройствах.

Мой PWA запущен и получает полные оценки на Chrome Devtools Аудит.

Я пытаюсь реализовать стратегию кэширования и затем сети. Кроме того, всякий раз, когда активируется новый сервисный работник, я хочу обновить sh кэш и получить обновленные файлы из сети.

Все отлично работает на настольном компьютере Chrome, но на устройствах iOS это просто отказывается очистить кеш и продолжает обслуживать устаревшие файлы даже после активации нового работника сервиса. Например, очистка кэша Safari вручную (!) Приведет к получению обновленной версии файла css.

Я даже пытался реализовать всплывающее уведомление, чтобы пользователь знал, что есть новая версия приложение, содержащее ссылку на sh сервисного работника, но опять же - оно хорошо работает на Chrome, но не обслуживает новые файлы на iOS - хотя оно показывает уведомление о новой версии всякий раз, когда служба Рабочий меняется, и нажав его перезагрузит страницу. Итак, я знаю, что сервисный работник обновляется на устройстве iOS, но он все еще обслуживает старые файлы.

Так как заставить устройства iOS обновить sh кэш и получить новый файлы?

Это код js, который регистрирует работника службы:

let newWorker; // Will hold the instance of the new sw so we can communicate with it

if ('serviceWorker' in navigator) {
// Register the service worker
navigator.serviceWorker.register(base_url + 'sw-test.js', { scope: base_url + 'test/' }).then(reg => {
    reg.addEventListener('updatefound', () => { // An updated service worker has appeared in reg.installing!
    newWorker = reg.installing;

    newWorker.addEventListener('statechange', () => { // Has service worker state changed?
        switch (newWorker.state) {
            case 'installed': // There is a new service worker available, show the notification
                if (navigator.serviceWorker.controller) {
                    $("#new_version_notification").removeClass("hidden_div");
                    $("#new_version_notification").addClass("show");
                }
                break;
             }
          });
       });
   });

}


// The click event on the notification
document.getElementById('reload').addEventListener('click', function(){
    console.log("clicked");
    newWorker.postMessage({ action: 'skipWaiting' });
    return false;
});

let refreshing;
// The event listener that is fired when the service worker updates
// Here we reload the page
navigator.serviceWorker.addEventListener('controllerchange', function () {
    if (refreshing) return;
    window.location.reload();
    refreshing = true;
});

А это мой код работника службы:

var CACHE_STATIC_NAME = 'static-v4';

var STATIC_FILES = [
    '../resources/fonts/fontawesome-pro/css/all.css',
    '../resources/css/mystyle.css',
    'https://code.jquery.com/jquery-3.4.1.min.js',
    'https://code.jquery.com/ui/1.12.1/jquery-ui.min.js'
    ];

//Cache Static Files:
self.addEventListener('install', function(event) {
    console.log('[Service Worker] Installing Service Worker ...', event);
    event.waitUntil(
    caches.open(CACHE_STATIC_NAME)
    .then(function(cache) {
        console.log('[Service Worker] Precaching App Shell');
        cache.addAll(STATIC_FILES);
    })
    .catch(function(err){
        console.log('****** error: ', err);
    })

    );
});

//Serve files from the chache (if found) or from the Network (if not)
self.addEventListener('fetch',function(event){
    event.respondWith(
    caches.match(event.request).then(function(response){ // if it finds a match to the request in any of the caches the promise is truthy
        if (response) return response;  // if it's truthy return what you found in the cache
        return fetch(event.request); // else return a regular fetch request
    })
    ); 
});


self.addEventListener('message', function (event) {
    if (event.data.action === 'skipWaiting') {
    self.skipWaiting();
    }
});

// Delete old cache: ('activate' is launched when the service worker has a new version, and after the user has closed all windows)
self.addEventListener('activate', function(event) {
    console.log('[Service Worker] Activating Service Worker ....', event);
    event.waitUntil(
    caches.keys() // caches.keys returns a Promise that resolves to an array of Cache keys.
    .then(function(keyList) {
        return Promise.all(keyList.map(function(key) { // Promise.all returns a single Promise that resolves when all of the promises in the iterable argument have resolved
        if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) {
            console.log('[Service Worker] Removing old cache.', key);
            return caches.delete(key);
        }
        }));
    })
    );
    return self.clients.claim();
});
...