安装 · 平台
iOS 添加到主屏幕
发布于 更新于
在 iOS 与 iPadOS 上,唯一的安装路径是用户自己的手势:共享,然后“添加到主屏幕”。Safari 从 iPhone OS 1 起就提供它;第三方浏览器自 iOS 16.4 起也可以提供;没有任何版本会触发 beforeinstallprompt 或暴露安装 API(BCD api.BeforeInstallPromptEvent),所以页面负责提供图标、名称与 manifest,而拿着设备的人决定图标如何启动,在 iOS 26 上这是一个明确的 “Open as Web App” 开关。
手势是固定的:点按共享,点按添加到主屏幕,可选地修改名称,点按添加。自 iOS 16.4 起,第三方浏览器在满足以下条件时可以提供同一菜单项:持有 com.apple.developer.web-browser 权限、把一个正在显示 HTTP 或 HTTPS 文档的 WKWebView 放入共享菜单的 activityItems,且设备不是共享 iPad(WebKit,“Web Push for Web Apps on iOS and iPadOS”)。
点按图标后发生什么,在 16.4 与 26 之间发生了变化:
| iOS 版本 | 以 web 应用方式打开(独立的应用切换器条目、无 Safari 界面)的条件 | 否则 |
|---|---|---|
| 16.4 至 18 | manifest 的 display 为 standalone 或 fullscreen,或旧的 apple-mobile-web-app-capable meta 标签为 yes;用哪个浏览器添加无关 |
保存为主屏幕书签,在默认浏览器中打开 |
| 26 | 默认对每个添加的站点都成立;用户可以在添加面板中关闭 “Open as Web App”,即使站点已配置为 web 应用 | 书签,仅当用户关闭了该开关 |
WebKit 对 26 的表述是:Safari 没有可安装性要求,不需要 manifest、不需要 service worker、除页面本身能加载外不检查 HTTPS。manifest 仍决定 web 应用的样子:icons 自 iOS 15.4 起被读取,name 与 short_name 作为可编辑标题的初始值,id(16.4+)与用户选定的名称组合,使同一站点的两次安装(“Shiny (work)” 与 “Shiny (personal)”)保持可区分,专注模式也能分别处理。同一站点多次安装是受支持且有意为之的。
其余由标记提供,优先级如下:
- 图标:同时存在时
<link rel="apple-touch-icon" sizes="180x180" href="…">优先于 manifest 的icons;Apple 的归档指南记载的选取顺序是最接近设备尺寸的图标、其次是比它大的最小图标、最后是最大的图标。完全没有图标时,iOS 16.4 及以后用站点名称首字母加站点取色生成一个字母图标。 - 名称:
<meta name="apple-mobile-web-app-title" content="…">,否则取<title>,用户添加前可编辑。 - 启动图:默认为上次启动的截图;
<link rel="apple-touch-startup-image" href="…">覆盖它,离线时尤其重要。 - 状态栏:
<meta name="apple-mobile-web-app-status-bar-style" content="black">仅在 standalone 模式下生效;Apple 归档指南写明它 “has no effect unless you first specify standalone mode”。
进入主屏幕后,web 应用获得 Safari 标签页没有的能力:Web Push(16.4+,需用户手势;18.4 的 Declarative Web Push 通过 window.pushManager 订阅,无需 service worker)、Badging API(16.4+,允许通知后绘制)、Screen Wake Lock、Screen Orientation 与 User Activation(均为 WebKit 在 16.4 中列出)。WebKit 在任何 iOS 版本中都没有要求主屏幕条目具备 service worker(WebKit,Safari 26.0 文章)。存储仍是尽力而为:开启跨站跟踪防护时,Safari 会删除在 7 天浏览器使用中没有任何交互的源所写入的脚本数据,navigator.storage.persist() 根据交互历史自动回答、不弹提示(MDN,存储配额与清除)。
下面的行为是读者可以在设备上复现的;页面无法观察安装本身,只能在事后观察显示上下文。
由于不存在安装事件,唯一有用的分支是显示上下文,用标准媒体特性判断,并以旧属性作为老版本 iOS 的回退:
const standalone = matchMedia('(display-mode: standalone)').matches || navigator.standalone === true; // 仅 Safari 的旧属性
if (standalone) { hideInstallHint(); // 从主屏幕启动} else if (/iPhone|iPad/.test(navigator.userAgent)) { showShareMenuInstructions(); // "点按共享,然后添加到主屏幕"}在第二次及之后的访问才显示提示,用触达换相关性;在已启动的 web 应用内显示提示则是噪音,上面的分支避免了这一点。user agent 判断只用于挑选说明文字;能力从 display-mode 读取。
- WebKit features in Safari 26.0(webkit.org)
- Web Push for Web Apps on iOS and iPadOS(webkit.org)
- Configuring Web Applications(developer.apple.com)
- iOS 与 Safari 上的 PWA
- iOS Safari 推送
- Badging API
idmanifest 成员- 可安装性条件
规范
| 规范 | 状态 |
|---|---|
| 无。 | |