Web端引导用户安装PWA全流程

0 阅读3分钟

写在前面

渐进式Web应用(PWA)是一种利用现代浏览器技术(如Service Workers和Web App Manifest)构建的Web应用,能提供类似原生APP的体验。
但是目前仅在Chrome系的浏览器上有较好的支持,Safari上的 文件-添加到程序坞 功能和PWA有很大的不同,Firefox直接不支持。

一、添加manifest.json文件

要想web应用支持安装到桌面,需要提供一个名为manifest.json的配置文件,通常放在public文件夹下,示例内容:

{
  "short_name": "App short name",
  "name": "App name",
  "icons": [
    {
      "src": "/images/pwa/icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/images/pwa/icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "id": "your-app-id",
  "start_url": "/",
  "background_color": "#06605A",
  "display": "standalone",
  "scope": "/",
  "theme_color": "#06605A",
  "description": "Here is the description",
  "screenshots": [
    {
      "src": "/images/pwa/screenshot-wide.png",
      "sizes": "1280x720",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Desktop App"
    },
    {
      "src": "/images/pwa/screenshot-narrow.png",
      "sizes": "540x720",
      "type": "image/png",
      "form_factor": "narrow",
      "label": "Mobile App"
    }
  ]
}

然后记得在index.html中导入:

<link rel="manifest" href="/manifest.json" />

此时重启项目,你会看到一个安装按钮出现在导航栏右边:

image.png

点击安装即可将网页安装到桌面。

到此,一个最简单的PWA应用已经配置完成了,但是这个安装按钮很多人注意不到,通常我们需要在web里加一个引导Banner,点击后可以直接拉起安装弹窗,那么还需要以下配置~

二、注册一个Service worker

首先在public文件夹下创建一个sw.js文件,添加一行最小内容:

self.addEventListener('fetch', () => {});

然后在项目内任意地方写一个初始化函数,我通常会放到 src/pwa/index.ts 文件下,内容如下:

import store from '@/store';

const initPWA = () => {
  // 注册一个空的service worker,否则无法手动触发pwa安装弹窗
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js').catch(() => {
      console.error('service worker registration failed');
    });
  }

  // pwa安装提示事件监听
  window.addEventListener('beforeinstallprompt', (e) => {
    // 只有chrome内核浏览器才会触发这个事件
    console.info('beforeinstallprompt event triggered');
    // 在这里保存一下事件e,用于后面手动触发pwa安装弹窗
    // 我这里用的全局状态管理工具是jotai,你也可以用别的,甚至挂载到window上也行
    store.set(pwaInstallPromptAtom, e as BeforeInstallPromptEvent);
  });

  // pwa安装成功事件监听
  window.addEventListener('appinstalled', () => {
    // 只有chrome内核浏览器才会触发这个事件
    console.info('appinstalled event triggered');
    // 我目前没有发现哪个api能判断当前是否已经安装了pwa,所以就只能用localStorage自己存一下
    localStorage.setItem('IS_PWA_INSTALLED', 'true');
  });
};

export default initPWA;

然后记得在整个项目的入口文件调用一下initPWA函数,准备工作就做完了~

三、手动触发安装pwa弹窗

React代码如下:

import { useAtomValue } from 'jotai';
import { isSafari } from 'react-device-detect';
import { pwaInstallPromptAtom } from '../store';

const GuideToPwaBanner = () => {
  // 拿到之前存的事件
  const pwaInstallPrompt = useAtomValue(pwaInstallPromptAtom);

  const handleInstall = async () => {
    if (pwaInstallPrompt) {
      // 拉起询问是否安装弹窗
      await pwaInstallPrompt.prompt();

      const { outcome } = await pwaInstallPrompt.userChoice;

      if (outcome === 'accepted') {
        // 走到这里就代表点了同意安装
      }
    } else if (isSafari) {
      // 如果是safari浏览器,可以引导“添加到程序坞”
    }
  };

  return <div onClick={handleInstall}>安装PWA</div>;
};

export default GuideToPwaBanner;

以上就是引导安装pwa的全部流程了~

写在末尾

1、配置了manifest.json,也没有出现安装按钮

image.png

在Devtools中可以检查是否成功加载了配置文件。

Service worker是否配置成功也可以在这个位置查看。

2、Safari的安装位置

image.png

这本质上是属于macos的能力,即使没有manifest.json也照样可以保存,但如果有manifest.json文件,那么添加到程序坞的应用程序也是可以读取到manifest的配置的。