操作系统集成

Web 应用的覆盖面非常广。它们可在多个平台上运行。您可以通过链接轻松分享它们。但传统上,它们缺乏与操作系统的集成。不久前,这些应用甚至无法安装。幸运的是,这种情况已经改变,现在我们可以利用这项集成为 PWA 添加实用功能。我们来探索其中的一些选项。

使用文件系统

使用文件的典型用户工作流程如下所示:

  • 从设备中选择一个文件或文件夹,然后直接打开。
  • 对这些文件或文件夹进行更改,然后直接将更改保存回来。
  • 创建新的文件和文件夹。

File System Access API 之前,Web 应用无法执行此操作。打开文件需要上传文件,保存更改需要用户下载,并且 Web 根本无法在用户的文件系统中创建新文件和文件夹。

打开文件

如需打开文件,我们使用 window.showOpenFilePicker() 方法。请注意,此方法需要用户手势,例如按钮点击。以下是打开文件的其余设置:

  1. 从文件系统访问的文件选择器 API 中捕获文件句柄。您可以从中了解该文件的基本信息。
  2. 使用句柄的 getFile() 方法,您将获得一种特殊的 Blob,称为 File,其中包含有关文件的其他只读属性(例如名称和上次修改日期)。由于它是 Blob,因此可以对其调用 Blob 方法(例如 text())来获取其内容。
// Have the user select a file.
const [ handle ] = await window.showOpenFilePicker();
// Get the File object from the handle.
const file = await handle.getFile();
// Get the file content.
// Also available, slice(), stream(), arrayBuffer()
const content = await file.text();

正在保存更改

如需保存对文件所做的更改,您还需要用户手势;然后:

  1. 使用文件句柄创建 FileSystemWritableFileStream
  2. 对数据流进行更改。这不会原地更新文件;通常,系统会创建一个临时文件。
  3. 最后,完成更改后,关闭数据流,这会将更改从临时更改转变为永久更改。

我们在代码中来看看这个过程:

// Make a writable stream from the handle.
const writable = await handle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();

文件处理

借助 File System Access API,您可以从应用内打开文件,但反之呢?用户希望将自己喜爱的应用设置为默认的文件打开方式。文件处理 API 是一项实验性 API,可让已安装的 PWA 执行以下操作:在用户设备上注册为文件处理程序,在 Web 应用清单中指定 PWA 支持的 MIME 类型和文件扩展名。您可以为受支持的扩展程序指定自定义文件图标。

注册后,已安装的 PWA 将显示为用户文件系统中的选项,用户可以直接在其中打开文件。以下是用于让 PWA 读取文本文件的清单设置示例:

...
"file_handlers": [
     {
         "action": "/open-file",
         "accept": {
             "text/*": [".txt"]
         }
     }
]
...

网址处理

借助网址处理功能,您的 PWA 可以从操作系统捕获其范围内的链接,并在 PWA 窗口(而非默认浏览器的标签页)中呈现这些链接。例如,如果您收到指向 PWA 的邮件,或者点击 PWA 中的深层链接(指向特定内容的网址),相应内容将在独立窗口中打开。

使用 WebAPK 时,Android 设备会自动提供此行为,例如当用户使用 Chrome 安装 PWA 时。无法通过 Safari 捕获安装在 iOS 和 iPadOS 上的 PWA 的网址。

对于桌面浏览器,网络浏览器社区创建了新的规范。此规范目前处于实验阶段;它添加了一个新的清单文件成员:url_handlers。此属性应为 PWA 要捕获的来源数组。系统会自动授予您的 PWA 的来源相应权限,并且所有其他来源都必须接受通过名为 web-app-origin-association 的文件进行操作的处理。例如,如果您的 PWA 的清单托管在 web.dev 上,并且您想添加 app.web.dev 源,则清单将如下所示:

"url_handlers": [
    {"origin": "https://app.web.dev"},
]

在这种情况下,浏览器会检查 app.web.dev/.well-known/web-app-origin-association 中是否存在文件,并接受来自 PWA 作用域网址的网址处理。开发者必须创建此文件。在以下示例中,该文件如下所示:

{
    "web_apps": [
        {
            "manifest": "/mypwa/app.webmanifest",
            "details": {
                "paths": [ "/*" ]
            }
        }
    ]
}

网址协议处理

网址处理适用于标准 https 协议网址,但也可以使用自定义 URI 架构,例如 pwa://。在某些操作系统中,已安装的应用通过注册其 scheme 来获得此能力。

对于 PWA,此功能是使用网址协议处理程序 API 启用的,该 API 仅适用于桌面设备。您只能通过在应用商店中分发 PWA 来为移动设备允许自定义协议。

如需进行注册,您可以使用 registerProtocolHandler() 方法,也可以在清单中使用 protocol_handlers 成员,并提供所需的架构和您要在 PWA 上下文中加载的网址,例如:

...
{
  "protocol_handlers": [
    {
      "protocol": "web+pwa",
      "url": "/from-protocol?value=%s"
    },
  ]
}
...

您可以将网址 from-protocol 路由到正确的处理脚本,并在 PWA 中获取查询字符串 value%s 是触发操作的已转义网址的占位符,因此,如果您在某个位置(例如 <a href="web+pwa://testing">)有链接,您的 PWA 将打开 /from-protocol?value=testing

调用其他应用

您可以使用 URI 架构在各个平台上连接到用户设备中的任何其他已安装应用(无论是 PWA 还是其他应用)。您只需创建一个链接或使用 navigator.href 并指向所需的 URI 架构,以网址转义形式传递参数即可。

您可以使用众所周知的标准 scheme,例如使用 tel: 进行通话、使用 mailto: 发送电子邮件或使用 sms: 发送短信;也可以了解其他应用的网址 scheme,例如众所周知的即时通讯、地图、导航、在线会议、社交网络和应用商店。

网页分享

Browser Support

  • Chrome: 89.
  • Edge: 93.
  • Firefox: behind a flag.
  • Safari: 12.1.

Source

借助 Web Share API,您的 PWA 可以通过共享渠道将内容发送到设备中已安装的其他应用。

此 API 仅适用于具有 share 机制的操作系统,包括 Android、iOS、iPadOS、Windows 和 ChromeOS。 您可以共享包含以下内容的对象:

  • 文本(titletext 属性)
  • 网址(url 属性)
  • 文件(files 属性)。

如需检查当前设备是否可以共享简单数据(例如文本),请检查是否存在 navigator.share() 方法;如需共享文件,请检查是否存在 navigator.canShare() 方法。

您可以通过调用 navigator.share(objectToShare) 请求执行分享操作。该调用会返回一个 promise,该 promise 会解析为 undefined 或因异常而被拒绝。

Android 版 Chrome 和 iOS 版 Safari 在 Web Share 的帮助下打开 Share Sheet。

Web Share Target

借助 Web Share Target API,您的 PWA 可以成为设备上其他应用(无论是 PWA 还是非 PWA)的共享操作目标。您的 PWA 会接收其他应用共享的数据。

该功能目前适用于搭载 WebAPK 的 Android 设备和 ChromeOS,并且仅在用户安装了您的 PWA 后才可使用。浏览器会在应用安装时在操作系统中注册共享目标。

您可以使用“网站共享目标”草稿规范中定义的 share_target 成员在清单中设置网站共享目标。share_target 会设置为具有以下属性的对象:

action
将在预计接收共享数据的 PWA 窗口中加载的网址。
method
系统将为操作使用 HTTP 动词方法,例如 GETPOSTPUT
enctype
(可选)参数的编码类型,默认为 application/x-www-form-urlencoded,但对于 POST 等方法,也可以设置为 multipart/form-data
params
一个对象,用于将分享数据(来自 Web Share 的键:titletexturlfiles)映射到浏览器将使用所选编码在网址(在 method: 'GET' 上)或请求正文中传递的参数。

例如,您可以通过在清单中添加以下代码,为 PWA 定义要接收的共享数据(仅限标题和网址):

...
"share_target": {
   "action": "/receive-share/",
   "method": "GET",
   "params": {
      "title": "shared_title",
      "url": "shared_url"
   }
}
...

在前面的示例中,如果系统中的任何应用都与标题共享网址,并且用户从对话框中选择您的 PWA,浏览器将创建指向您来源的 /receive-share/?shared_title=AAA&shared_url=BBB 的新导航,其中 AAA 是共享的标题,BBB 是共享的网址。您可以使用 JavaScript 通过 URL 构造函数解析 window.location 字符串,从中读取数据。

浏览器将使用清单中的 PWA 名称和图标来填充操作系统的分享条目。您无法为此目的选择其他组合。

如需查看更详细的示例以及如何接收文件,请参阅使用 Web Share Target API 接收共享数据

联系人选取工具

Browser Support

  • Chrome: not supported.
  • Edge: not supported.
  • Firefox: not supported.
  • Safari: not supported.

Source

借助 Contact Picker API,您可以请求设备呈现包含用户所有联系人的原生对话框,以便用户选择一个或多个联系人。然后,您的 PWA 便可从这些联系人那里接收所需的数据。

Contact Picker API 主要适用于移动设备,所有操作均通过兼容平台上的 navigator.contacts 界面完成。

您可以使用 navigator.contacts.getProperties() 请求可供查询的属性,并请求选择一个或多个联系人,以及所需属性的列表。

一些示例属性包括 nameemailaddresstel。当您要求用户选择一个或多个联系人时,可以调用 navigator.contacts.select(properties),并传递您希望在返回时获取的一系列属性。

以下示例将列出选择器收到的联系人。

async function getContacts() {
   const properties = ['name', 'email', 'tel'];
   const options = { multiple: true };
   try {
     const contacts = await navigator.contacts.select(properties, options);
     console.log(contacts);
   } catch (ex) {
     // Handle any errors here.
   }
}

资源