PWA 中 IOS 系统安装桌面的问题解决方案
在 PWA 的世界里,IOS 系统中的移动端网页应用也能通过添加到主屏幕的方式来实现安装到桌面上,提升用户体验。但是,IOS 系统对于 PWA 的支持并不完善,导致在添加到主屏幕的过程中出现了一些问题。本文将介绍 IOS 系统中 PWA 安装桌面的问题及解决方案。
问题描述
在 IOS 系统中,添加到主屏幕的 PWA 应用不能够像 APP 一样在桌面上直接打开,而是需要经过 Safari 浏览器的中转,用户需要先打开 Safari,然后通过 Safari 打开 PWA 应用。这对于用户来说会降低用户体验,因此,需要在解决方案里解决这个问题。
解决方案
为了解决添加到主屏幕的 PWA 应用需要在 Safari 中打开的问题,我们可以使用一个优秀的库 - pwa-helper. pwa-helper 提供的解决方案可以实现在 IOS 系统中打开 PWA 应用的时候不经过 Safari 浏览器,直接在桌面上打开 PWA 应用。下面我们来看一下具体的实现。
- 在 PWA 应用根目录下新建一个名为
sw.js
的文件来实现 Service Worker.
const cacheName = 'pwa-v1.2'; const cacheFiles = [ '/', '/index.html', '/manifest.json', '/sw.js', '/images/icon.png', '/images/icon-192.png', '/images/icon-512.png', ]; self.addEventListener('install', e => { e.waitUntil( caches.open(cacheName).then(cache => { return cache.addAll(cacheFiles); }) ); }); self.addEventListener('fetch', e => { e.respondWith( caches.match(e.request).then(res => { if (res) return res; return fetch(e.request); }) ); });
- 在 index.html 中引入 pwa-helper 库。
<head> ... <script src="./pwa-helper.js"></script> ... </head>
- 在 index.html 的 body 标签里添加一段 JavaScript 代码来调用 pwa-helper 库中的相关方法。
<body> ... <script> PWAHelpers.initializeIOS(); ... </script> ... </body>
- 配置 PWA 应用的 manifest.json 文件。需要注意的是,在 IOS 系统中添加到主屏幕的 PWA 应用需要配置 apple-touch-icon,否则不会有图标显示。
{ "short_name": "PWA 应用", "name": "PWA 应用", "theme_color": "#ffffff", "background_color": "#ffffff", "start_url": "/index.html", "icons": [ { "src": "/images/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" }, { "src": "/images/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" } ], "display": "standalone", "orientation": "portrait", "scope": "/", "apple-touch-icon": "/images/icon.png" }
示例代码
上面讲到的代码已经能够解决在 IOS 系统中添加到主屏幕的 PWA 应用需要在 Safari 中打开的问题,我们可以通过如下步骤运行一个示例:
下载 pwa-helper 库到 PWA 应用项目根目录。
在 src 根目录下新建一个名为
pwa-helper.js
的文件来引入下载的 pwa-helper 库。
import * as PWAHelpers from '/pwa-helper.js'; window.PWAHelpers = PWAHelpers;
- 配置 manifest.json 文件。
{ "short_name": "PWA 示例", "name": "PWA 示例", "theme_color": "#ffffff", "background_color": "#ffffff", "start_url": "/index.html", "icons": [ { "src": "/images/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" }, { "src": "/images/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" } ], "display": "standalone", "orientation": "portrait", "scope": "/", "apple-touch-icon": "/images/icon.png" }
- 配置 sw.js 缓存服务。
const cacheName = 'pwa-v1.2'; const cacheFiles = [ '/', '/index.html', '/manifest.json', '/sw.js', '/images/icon.png', '/images/icon-192.png', '/images/icon-512.png', ]; self.addEventListener('install', e => { e.waitUntil( caches.open(cacheName).then(cache => { return cache.addAll(cacheFiles); }) ); }); self.addEventListener('fetch', e => { e.respondWith( caches.match(e.request).then(res => { if (res) return res; return fetch(e.request); }) ); });
- 在 index.html 中添加调用 pwa-helper 库的相关代码。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="theme-color" content="#ffffff"/> <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/> <title>PWA 示例</title> <link rel="manifest" href="./manifest.json"> <link rel="icon" href="./images/favicon.ico"> <link rel="apple-touch-icon" href="./images/icon.png"> <script src="./pwa-helper.js"></script> </head> <body> <h1>PWA 示例</h1> <p>这是一个 PWA 示例页面</p> <script> PWAHelpers.initializeIOS(); </script> </body> </html>
- 在终端运行以下命令开启 PWA 应用。
npx http-server
运行成功后,会提示这样一条信息:
Starting up http-server, serving ./ Available on: http://127.0.0.1:8080 http://192.168.0.103:8080
- 在 Safari 浏览器中打开页面
http://127.0.0.1:8080/index.html
,可以看到页面上有一个添加到主屏幕的按钮。在弹出的添加到主屏幕对话框中,输入应用名称并确认添加即可将 PWA 应用安装到桌面。
总结
本文介绍了在 IOS 系统中添加 PWA 应用到桌面时需要经过 Safari 中转的问题以及解决方案。通过使用 pwa-helper 库,实现了在 IOS 系统中添加到主屏幕的 PWA 应用时不需要经过 Safari 浏览器的功能。同时,本文也提供了 PWA 应用示例代码,帮助开发者更好地理解和使用 pwa-helper 库。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65aa24dbadd4f0e0ff3b3f45