关于通知的注意事项
编辑
在开始之前了解通知类型及其行为。
通知是告知用户新信息或事件的警报,即使应用程序未在使用中。它们的覆盖范围很大,平台之间的差异可能使实现通知变得令人生畏。
无论您是刚开始接触通知,还是已有一定了解,本文件均会解释不同类型的通知及其行为。
Expo 的通知支持建立在 Android 和 iOS 提供的原生功能之上。来自原生平台的相同概念和行为适用于 Expo 应用。如果您对特定的通知功能感到不确定,请参见每个平台的 官方文档。
远程和本地通知
- 推送通知:(也称为“远程通知”)从远程服务器发送到用户设备的通知。
- 本地通知:(也称为“应用内通知”)在应用程序内部创建和显示的通知。由于创建这些通知的许多 API 将在特定时间创建它们,因此这些通知有时也称为“定时通知”。
expo-notifications 支持推送和本地通知。您必须使用 开发版本 才能使用推送通知,因为此功能未内置到 Expo Go 中。
有关如何创建和显示本地通知,请参见 应用内通知。本指南的其余部分重点关注推送通知。
推送通知的传递
当推送通知到达您的应用程序时,其行为取决于应用程序的状态和通知类型。让我们澄清术语:
应用程序状态
- 前台:应用程序在前台积极运行。其界面当前显示在屏幕上。
- 后台:应用程序在后台运行,“最小化”。其界面当前未显示在屏幕上。
- 已终止:应用程序被“关闭”,通常是在应用切换器中通过滑动手势关闭。在 Android 上,如果用户从设备设置强制停止应用程序,则必须手动重新打开才能使通知开始工作(这是 Android 的一个限制)。
推送通知的行为
对于任何类型的通知,当应用程序在前台时,应用程序控制如何处理传入的通知。应用程序可以直接展示它,显示一些自定义的应用内 UI,甚至忽略它(这由 NotificationHandler 控制)。当应用程序不在前台时,行为取决于通知的类型。
下表总结了推送通知传递到设备时发生的情况:
| 通知类型 | 应用在前台 | 应用在后台 | 应用已终止 |
|---|---|---|---|
| 通知消息 和 含数据负载的通知消息 | 传递运行 NotificationReceivedListener 和 JS 任务 | 操作系统显示通知 | 操作系统显示通知 |
| 无头后台通知 | 传递运行 NotificationReceivedListener 和 JS 任务 | 传递运行 JS 任务 | 传递运行 JS 任务 |
当用户与通知交互时(例如,按下操作按钮),以下处理程序将提供给您。
| 应用状态 | 触发的 iOS 监听器 | 触发的 Android 监听器 |
|---|---|---|
| 前台 | NotificationResponseReceivedListener | NotificationResponseReceivedListener |
| 后台 | NotificationResponseReceivedListener | NotificationResponseReceivedListener 和 JS 任务 |
| 已终止 | NotificationResponseReceivedListener | JS 任务 |
在上表中,每当 NotificationResponseReceivedListener 被触发,useLastNotificationResponse 的返回值也会发生变化。
当应用程序未运行或已终止,并通过点击通知启动时,NotificationResponseReceivedListener必须提前注册(模块顶层),以便在 iOS 上触发。对于将应用程序带到前台的操作按钮,我们建议在应用程序启动后使用useLastNotificationResponse或getLastNotificationResponse捕获响应。
推送通知类型
通知消息
通知消息是指定展示信息的通知,如标题或正文文本。
- 在 Android 上,这相当于包含
AndroidNotification的推送通知请求。 - 在 iOS 上,这相当于包含
aps.alert字典 和apns-push-type头设置为alert的推送通知请求。
当您使用 Expo 推送服务,并指定 title、subtitle、body、icon 或 channelId 时,生成的推送通知请求即为通知消息。
通知消息的典型用例是立即向用户展示,而没有额外的处理。
含数据负载的通知消息
这是一个仅限 Android 的术语 (查看官方文档),其中推送通知请求同时包含 data 字段和 notification 字段。
在 iOS 上,额外数据可能是常规通知消息请求的一部分。Apple 不区分是否携带数据的通知消息。
无头后台通知
无头通知是一种远程通知,它不直接指定展示信息,如标题或正文文本。除了下面的例外*,无头通知不会展示给用户。相反,它们携带数据(JSON),由您通过 registerTaskAsync 在应用中定义的 JavaScript 任务进行处理。该任务可以执行任意逻辑。例如,写入 AsyncStorage、进行 API 请求或展示本地通知,其内容来自推送通知的数据。
无头后台通知能够在收到通知时运行自定义 JavaScript 即使应用已终止。这很强大,但也有一个限制:即使通知已传递到设备,操作系统也不保证将其传递到您的应用程序。这可能由于多种原因发生,例如,当 Android 上启用 待机模式 时,或者当您发送太多后台通知时 — Apple 建议不要 每小时发送超过两个或三个。
当您使用 Expo 推送服务,并仅指定 data 和 _contentAvailable: true(以及其他非交互字段,如 ttl)时,生成的推送通知请求会产生无头后台通知。
要在 iOS 上使用无头后台通知,您必须首先 配置 它们。
通常的原则是,如果您不需要在后台运行 JavaScript,最好使用常规通知消息。
* 例外是当您在 data 中指定 title 或 message 时。此时,expo-notifications 包会自动在 Android 上展示无头通知,但在 iOS 上则不会。我们计划在未来的版本中使这种行为在各个平台之间更加一致。
仅数据通知
Android 有 数据消息 的概念。iOS 并没有完全相同的概念,但一个较接近的等价体是 无头后台通知。
您可能还会遇到“静默通知”这一术语,这是指不向用户展示任何内容的通知 — 我们将这些描述为 无头后台通知。
外部参考
这是关于 Android 和 iOS 推送通知的官方资源的非详尽列表: