主屏幕网络应用图标角标

除了 iOS 和 iPadOS 16.4 中许多其他网络应用功能外,WebKit 现在还支持 W3C 的Badging API

A badged web application icon in the iOS dock showing the number 15.

这个直接的 API 允许网络开发者为网络应用图标添加角标。本文将探讨 Badging API 的各种功能及其使用方法,以及我们与 W3C 的Web Applications Working Group正在进行的合作,以改进规范。

主屏幕网络应用可用性

在 iOS 和 iPadOS 16.4 中,Badging API 仅适用于用户已添加到其主屏幕的网络应用。您不会在 Safari 或其他浏览器中的网站,或任何使用 WKWebView 的应用中找到此 API。

您可以通过对 setAppBadge 函数进行功能检测,轻松检查 API 的可用性

if ('setAppBadge' in navigator) {
  // API is available...
}  

角标和通知

在 iOS 和 iPadOS 上,角标始终与通知紧密相关。

为 macOS、iOS 和 iPadOS 构建的应用可以随时通过平台特定的 API 设置其角标计数。用户必须授予应用显示通知的权限,角标才会出现。

同样,网络应用可以随时调用 setAppBadge(),但只有在用户授予通知权限后,角标才会出现。

要请求通知权限,请在用户激活(例如按钮点击)中调用 Notification.requestPermission()

<button onclick="requestNotificationPermission()">
  Request notifications permission
</button>

<script>
  async function requestNotificationPermission() {
    const permission = await Notification.requestPermission();
    if (permission === 'granted') {
      // You can now use the Badging API
    }
  }
</script>

iOS 和 iPadOS 将向用户显示此系统提示以获取权限

A browser permission prompt for asking the user to allow web notifications.

您还可以通过使用权限 API来检查用户是否已授予通知权限

async function checkNotificationPermission() {
  const permissionStatus = await navigator
    .permissions
    .query({ name: 'notifications' });

  switch (permissionStatus.state) {
    case 'granted':
      // You can use the Badging API
      break;
    case 'denied':
      // The user has denied the permission
      break;
    default:
      // The user has not yet granted or denied the permission
      await requestNotificationPermission();
      break;
  }
}
checkNotificationPermission();

请注意,即使用户可能已授予通知权限,他们仍可以通过 iOS 或 iPadOS 设置来控制该权限。由于有些用户觉得角标令人分心,他们可能会保持通知权限启用,但选择不显示角标。

为了保护用户隐私,我们从不将此用户偏好暴露给网络应用。

从网络应用设置和清除角标

应用角标表示需要用户注意的项目数量(例如,“您有 5 条未读消息”)。数字的含义取决于应用程序。

An application badge icon showing a badge with the number 5.

要更新应用程序图标角标,请向 navigator.setAppBadge() 方法传递一个正数

async function setBadge(count) {
  if ('setAppBadge' in navigator) {
    try {
      await navigator.setAppBadge(count);
    } catch (error) {
      console.error('Failed to set app badge:', error);
    }
  }
}

// Set the badge count to 5
setBadge(5);

您可以通过使用 navigator.clearAppBadge() 来清除角标。

async function clearBadge() {
  if ('clearAppBadge' in navigator) {
    try {
      await navigator.clearAppBadge();
    } catch (error) {
      console.error('Failed to clear app badge:', error);
    }
  }
}

// Clear the badge
clearBadge();

或者,调用 navigator.setAppBadge(0) 等同于调用 navigator.clearAppBadge()

从 Service Worker 使用 API

除了暴露给 window 对象外,Badging API 还暴露在Web Worker上下文中。

这使得它对于支持Web Push的应用特别有用,因为当您的Service Worker处理 push 事件时,更新应用程序角标非常简单。

// Function to determine the badge count based on the event data
function determineBadgeCount(data) {
  // Process the data to compute the badge count
}

self.addEventListener('push', (event) => {
  let promises = [];

  if ('setAppBadge' in self.navigator) {
    const badgeCount = determineBadgeCount(event.data);
    // Promise to set the badge
    const promise = self.navigator.setAppBadge(badgeCount);
    promises.push(promise);
  }

  // Promise to show a notification
  promises.push(self.registration.showNotification("You've got mail!"));

  // Finally...
  event.waitUntil(Promise.all(promises));
});

在请求推送订阅时,您必须承诺所有推送都是用户可见的事件。这意味着您处理的每个 push 事件必须通过调用 self.registration.showNotification() 显示用户可见的通知。

建议您在处理 push 事件时更新应用程序角标,但仅靠角标更新本身并不能满足“用户可见”的要求;请继续显示这些通知!

第三方安全限制

当用户将您的网络应用添加到其主屏幕时,他们表示了对您作为第一方的信任。

调用 navigator.setAppBadge() 以尝试更新角标计数的 JavaScript 必须来自与您的顶级文档同源的框架。从跨源框架调用 navigator.setAppBadge() 将无效。

在 W3C 发展 Badging API

我们正在与 W3C Web Applications Working Group 及其成员合作,特别是与微软合作,他们作为 Badging API 规范的共同编辑与我们合作。这种合作使我们能够跨浏览器和操作系统创建更一致、更安全、更注重隐私的 API。Badging API 规范之前由 Google 的人员编辑。我们很高兴与 W3C 成员合作,继续其发展。