web-dev-qa-db-fra.com

Est-il encore possible de mettre à jour automatiquement (ou simplement de vider le cache) un PWA sur iOS?

J'ai eu du mal sur iOS avec quelque chose qui fonctionne facilement sur Android: obtenir la mise à jour automatique de mon PWA lorsqu'il y a une nouvelle version. Je ne suis pas du tout sûr que cela soit même possible sur iOS. J'ai utilisé vue.js et Quasar pour créer mon application, et tout fonctionne par défaut sur Android. Voici la façon (laide, terrible) dont les choses se présentent actuellement sur la version iOS:

  1. Je peux vérifier la version de mon propre serveur et la comparer à celle actuellement stockée dans mon application (dans indexedDB) et afficher un avis qu'il existe une nouvelle version. Jusqu'ici tout va bien.
  2. À part le fait que l'utilisateur EFFACE MANUELLEMENT LA CACHE SAFARI (!!), je ne peux pas comprendre comment effacer par programmation le cache PWA depuis l'application ou forcer le téléchargement d'une autre manière.

Donc, à ce stade, je suppose que mes questions sont les suivantes:

  1. Quelqu'un a-t-il pu obtenir un PWA sur iOS (11.3 ou version ultérieure) pour se mettre à jour automatiquement lorsqu'une nouvelle version est disponible?
  2. Existe-t-il un moyen d'effacer le cache de l'application (safari) depuis mon PWA?

Évidemment, c'est une expérience utilisateur incroyablement horrible de notifier à l'utilisateur que pour mettre à jour, il doit effectuer plusieurs étapes en dehors de l'application pour pouvoir la rafraîchir, mais il semble que c'est la situation d'iOS en ce moment, sauf si je manque quelque chose. Quelqu'un at-il fait quelque part ce travail?

6
Stephen

Après des semaines et des semaines de recherches, j'ai finalement trouvé une solution:

  1. J'ajoute une vérification de la chaîne de version sur le serveur et je la renvoie à l'application comme mentionné ci-dessus.

  2. Je le cherche dans localtstorage (IndexedDB) et si je ne le trouve pas, je l’ajoute. Si je le trouve, je compare les versions et s'il y en a une plus récente sur le serveur, je lance une boîte de dialogue.

  3. La fermeture de cette boîte de dialogue (mon bouton est intitulé "mise à jour") exécute window.location.reload(true) puis stocke la nouvelle chaîne de version dans localstorage

Voila! Mon application est mise à jour! Je ne peux pas croire que cela se résume à quelque chose d'aussi simple, je n'ai trouvé aucune solution nulle part. J'espère que ceci aide quelqu'un d'autre!

MISE À JOUR SEPT 2019:

Il y avait quelques problèmes avec la technique ci-dessus, notamment qu'elle contournait les mécanismes de l'agent de service PWA et que parfois le rechargement ne chargeait pas immédiatement le nouveau contenu (parce que le SW actuel ne publierait pas la page). J'ai maintenant une nouvelle solution à cela qui semble fonctionner sur toutes les plateformes:

forceSWupdate () {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.getRegistrations().then(function (registrations) {
      for (let registration of registrations) {
        registration.update()
      }
    })
  }
}

Et à l'intérieur de mon serviceworker, je lance maintenant la boîte de dialogue s'il y a une mise à jour et je fais ma location.reload(true) à partir de là. Cela se traduit toujours par une actualisation immédiate de mon application (avec l'importante mise en garde que j'ai ajoutée les directives skipWaiting et clientsClaim à mon enregistrement).

Cela fonctionne de la même manière sur chaque plate-forme, et je peux vérifier par programmation la mise à jour ou attendre que le technicien le fasse par lui-même (bien que les temps qu'il vérifie varient considérablement selon la plate-forme, l'appareil et d'autres facteurs inconnaissables. Généralement pas plus de 24 heures cependant.)

13
Stephen