21

我在 iOS 上一直在努力使用在 Android 上可以轻松运行的东西:让我的 PWA 在有新版本时自动更新。我完全不确定这在 iOS 上是否可行。我已经使用 vue.js 和 Quasar 来构建我的应用程序,并且一切都在 Android 上开箱即用。这是目前在 iOS 版本上的(丑陋,可怕)方式:

  1. 我可以检查我自己的服务器的版本,并将其与存储在我的应用程序(在 indexedDB 中)中的当前版本进行比较,并发出一个通知,指出有一个新版本。到目前为止,一切都很好。
  2. 除了让用户手动清除 SAFARI 缓存(!!)之外,我无法弄清楚如何以编程方式从应用程序中清除 PWA 缓存或以其他方式强制上传。

所以在这一点上,我想我的问题是:

  1. 是否有人能够在 iOS(11.3 或更高版本)上获得 PWA 以在新版本可用时自动更新?
  2. 有没有办法从我的 PWA 中清除(safari)应用程序缓存?

显然,通知用户为了更新他们必须在应用程序之外执行几个步骤才能刷新它,这是一种非常糟糕的用户体验,但似乎这就是 iOS 目前所处的位置,除非我错过了一些东西。有没有人在任何地方完成这项工作?

4

3 回答 3

30

经过数周和数周的搜索,我终于找到了解决方案:

  1. 我在服务器上添加了对版本字符串的检查,并将其返回给应用程序,如上所述。

  2. 我在 localtstorage (IndexedDB) 中查找它,如果找不到,我添加它。如果找到了,我会比较版本,如果服务器上有更新的版本,我会弹出一个对话框。

  3. 关闭此对话框(我的按钮标记为“更新”)运行window.location.reload(true),然后将新版本字符串存储在本地存储中

瞧!我的应用更新了!我不敢相信它归结为这么简单,我在任何地方都找不到解决方案。希望这对其他人有帮助!

2019 年 9 月更新:

上述技术存在一些问题,特别是它绕过了 PWA 服务工作者机制,并且有时重新加载不会立即加载新内容(因为当前的 SW 不会释放页面)。我现在有一个似乎适用于所有平台的新解决方案:

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

在我的服务人员内部,如果有更新,我现在会弹出对话框,然后location.reload(true)从那里执行我的操作。这总是会导致我的应用程序立即刷新(我添加的重要警告skipWaitingclientsClaim注册指令)。

这在每个平台上都一样,我可以以编程方式检查更新或等待服务人员自行完成(尽管它检查的时间因平台、设备和其他未知因素而有很大差异。通常不超过 24小时虽然。)

于 2018-09-08T19:35:59.500 回答
5

如果有人对此仍有疑问,registration.update() 对我不起作用。我使用了确切的解决方案,但是当我的服务器上的版本与我的本地存储版本不匹配时,我必须取消注册服务人员才能使其工作。

  if ('serviceWorker' in navigator) {
   await this.setState({ loadingMessage: 'Updating Your Experience' })
   navigator.serviceWorker.getRegistrations().then(function(registrations) {
    registrations.map(r => {
      r.unregister()
    })
   })
   await AsyncStorage.setItem('appVersion', this.state.serverAppVersion)
   window.location.reload(true)
  } 

然后,当应用重新加载时,Service Worker 会重新注册,并且应用的当前版本在 iOS Safari 浏览器和“已添加书签”的 PWA 上可见。

于 2020-08-17T16:48:32.907 回答
1

除了提示用户新版本可用之外,您还可以扩展“激活”事件侦听器以在发布新的 serviceworker 版本时删除旧缓存。

  1. 添加版本和名称变量
var version = "v3" // increase for new version
var staticCacheName = version + "_pwa-static";
var dynamicCacheName = version + "_pwa-dynamic";
  1. 删除缓存,当它们的名称不适合当前版本时:
self.addEventListener('activate', function(event) {
    event.waitUntil(
        caches.keys().then(function(cacheNames) {
            return Promise.all(
                cacheNames.filter(function(cacheName) {
                    if (!cacheName.startsWith(staticCacheName) &&
                        !cacheName.startsWith(dynamicCacheName)) {
                        return true;
                    }
                }).map(function(cacheName) {
                    console.log('Removing old cache.', cacheName);
                    return caches.delete(cacheName);
                })
            );
        })
    );
});

(学分:https ://stackoverflow.com/a/45468998/14678591 )

为了使 iOS safari 浏览器和“书签”PWA 也可以使用,我刚刚添加了 @jbone107 略微简化的功能:

self.addEventListener('activate', function(event) {
    event.waitUntil(
        caches.keys().then(function(cacheNames) {
            return Promise.all(
                cacheNames.filter(function(cacheName) {
                    if (!cacheName.startsWith(staticCacheName) &&
                        !cacheName.startsWith(dynamicCacheName)) {
                        return true;
                    }
                }).map(function(cacheName) {
                    // completely deregister for ios to get changes too
                    console.log('deregistering Serviceworker')
                    if ('serviceWorker' in navigator) {
                        navigator.serviceWorker.getRegistrations().then(function(registrations) {
                            registrations.map(r => {
                                r.unregister()
                            })
                        })
                        window.location.reload(true)
                    }

                    console.log('Removing old cache.', cacheName);
                    return caches.delete(cacheName);
                })
            );
        })
    );
});

这样你只需要增加版本号,更新由 serviceworker 自动完成。

于 2021-12-13T13:30:08.393 回答