iOS 中的推送通知

2025年03月17日 | 阅读 9 分钟

推送通知是应用程序开发者与用户互动最简单的方式。推送通知允许开发者在用户点击通知时执行小任务。即使设备处于后台,我们也可以触发推送通知到设备。在本教程中,我们将配置 iOS 应用程序以接收推送通知。

通常,推送通知是由 Apple Push Notification Service (APNS) 触发的消息。应用程序可以接收推送通知,即使它没有运行或设备不活跃。推送通知可用于在应用程序内执行以下操作。

  1. 向用户显示一些警报,告知应用程序的更新。
  2. 在应用程序图标上设置或更新徽章计数,以了解新项目。
  3. 用户还可以通过推送通知执行一些小操作,而无需打开应用程序。
  4. 显示媒体附件。
  5. 编辑或删除已发送的通知。
  6. 播放通知声音。

前提条件

要向 iOS 应用程序发送推送通知,我们需要以下设置。

  1. Xcode 11.4 或更高版本:在 Xcode 11.4 之前,推送通知只能在设备上接收。但是,自 Xcode 11.4 以来,Apple 已为模拟器提供了接收推送通知的支持。
  2. Apple 开发者帐户:我们需要 Apple 开发者计划会员资格来生成 APNS 证书并将其添加到应用程序的标识符中。

发送和接收推送通知

让我们开始配置我们的 iOS 项目以接收推送通知。在此过程中,我们将在 Xcode 和 Apple 开发者帐户中进行配置。之后,我们将发送模拟推送通知来测试应用程序。本教程将使用 Xcode 12.0.1

请考虑以下步骤来配置 Xcode 项目。

1. 在 Xcode 12 中创建一个新的 iOS 项目,并提供一个已在 Apple Developer 帐户中注册的 App ID。但是,我们稍后可以在 Xcode 中更改捆绑包标识符 (App ID)。要在 Xcode 中更改捆绑包标识符,请选择 Xcode 目标,然后在“常规”部分更改捆绑包标识符,如下图所示。

Push Notifications in iOS

2. 我们需要与 Apple Developer 帐户注册相同的 App ID 并启用推送通知权限。要在 Apple Developer 帐户中创建 App ID,请导航到“证书、标识符和配置文件”部分中的“标识符”,然后单击“+”图标。这将弹出以下窗口。

Push Notifications in iOS

在上面的窗口中,选择 App IDs,然后单击“继续”。下一个窗口将提示我们选择正在为其创建 App ID 的目标(App 或 App Clip)。选择 App 并继续。下一个窗口将提示我们输入常规信息,如 App ID 名称(组织的逆域名前缀,包括应用程序名称)和描述。提供信息并单击“继续”。

这将生成我们的捆绑包标识符。现在,我们需要为应用程序添加推送通知功能。我们需要在 Xcode 和开发者帐户中提供此功能。要添加 Xcode 功能,请转到项目目标 -> 签名和功能,然后单击“+”图标。这将提示我们选择需要添加的功能。请参考下图。

Push Notifications in iOS

要在开发者帐户中添加功能,请转到“证书、标识符和配置文件”部分的“标识符”。选择我们为应用程序创建的 App ID 进行编辑。请参考下图将功能添加到 App ID。

Push Notifications in iOS

将推送通知功能添加到 Xcode 项目后,项目应如下图所示。

Push Notifications in iOS

现在,我们将实现接收 iOS App 中推送通知所需的方法。

请求用户权限

我们必须征得用户同意才能显示通知。为此,请在 AppDelegate 的顶部导入 UserNotifications

我们需要将以下方法添加到 AppDelegate 并从 application(_:didFinishLaunchingWithOptions) 中调用它。

UserNotification中心用于处理与通知相关的活动。requestAuthorization(options:completionHandler: ) 用于请求用户显示通知的授权。可以在 completion handler 中传递的 UNAuthorizationOptions 的各种组合如下。

  1. .badge:此选项指定应用程序图标上显示的新项目数量,以通知用户。
  2. .sound:此选项用于在通知到来时播放声音。
  3. .alert:此选项指定文本通知。
  4. .carPlay:此选项要求用户在 CarPlay 中显示通知。
  5. .provisional:如果我们选择此选项,将不会向用户请求权限。但是,通知将在通知中心静默显示。
  6. .providesAppNotificationSettings:它指定应用程序使用其界面进行通知设置。
  7. .criticalAlert:它仅用于某些特殊情况。我们需要 Apple 的特定权限来请求用户同意此权限,因为此选项会忽略静音开关和勿扰模式。

application(_:didFinishLaunchingWithOptions) 将包含以下代码。

现在,当我们构建并运行我们的应用程序时。它将提示我们提供权限,如下图所示。

Push Notifications in iOS

用户必须点击“允许”才能授予应用程序显示推送通知的权限。用户可能不允许该应用程序,在这种情况下,我们必须在 AppDelegate 中添加以下方法。

现在,我们必须用以下代码替换 registerForPushNotifications() 方法的代码。

注册 APNs

我们必须向 APNs 注册我们的应用程序才能获得推送通知。用以下代码替换 getNotificationSettings() 方法的代码,它将验证 authorizationStatus。如果状态为 .authorized,我们必须调用 UIApplication.shared.registerForRemoteNotifications() 方法来注册 APNs。

获取设备令牌

我们需要将设备令牌提供给发送推送通知到应用程序的服务器。它在服务器端作为应用程序的地址。要获取设备令牌,我们需要添加以下代码来获取设备令牌。

当 registerForRemoteNotifications() 调用成功时,将调用上述方法。设备令牌是由 APNs 提供的设备标识符,用于唯一标识设备。

但是,如果 registerForRemoteNotifications() 调用失败,iOS 将调用以下方法,我们必须将其添加到 AppDelegate 中。

我们只能在我们实际设备上运行应用程序时检索设备令牌。由于我们目前正在模拟器上运行,因此会在控制台中打印“Failed to register”消息。

向应用程序发送推送通知

现在,我们在 Apple Developer 帐户和 Xcode 应用程序中完成了必要的设置。我们的应用程序已准备好接收推送通知。要测试应用程序,我们需要发送模拟推送通知到应用程序。为此,请创建一个名为 push.apn 的文件,将其传递给 Xcode 以测试推送通知。将以下 JSON 文本保存在 push.apn 文件中。

现在,构建并运行应用程序。

要模拟推送通知,我们必须知道我们正在运行应用程序的模拟器的设备标识符。为此,请转到 Xcode -> 窗口 -> 设备和模拟器,如下图所示。

Push Notifications in iOS

现在,从模拟器列表中选择模拟器并复制设备标识符。我们将在以下命令中提供设备标识符和捆绑包标识符。

在这里,我们必须确保我们在终端中处于保存 push.apn 文件的目录中。我们必须将设备标识符替换为我们刚刚从 Xcode 复制的标识符,并将捆绑包标识符替换为我们在 Xcode 和 Apple Developer 帐户中提供的标识符。

运行此命令后,我们将在模拟器中收到推送通知,如下图所示。

Push Notifications in iOS

推送通知正文

让我们看一下我们发送到模拟器的通知的正文。推送通知的负载如上所示。

它是一个 JSON 字典,其中包含一个名为 aps 的项,它本身也是一个字典。这里,aps 字典包含三个字段,即 alert、sound 和 link_url。但是,aps 字典中可以添加 8 个内置键,如下所示。

  1. alert:它指定通知显示一个带有指定文本的警报视图。它可以是字符串或字典。
  2. badge:它指定要设置在应用程序图标上的数字,以告知用户有新项目。但是,可以通过将 badge 设置为 0 来删除它。
  3. sound:此指定应用程序中声音文件的名称。但是,我们可以为通知设置默认声音。应用程序中的声音不能超过 30 秒。
  4. thread-id:此键可用于对通知进行分组。
  5. category:category 用于指定要在通知上执行的自定义操作的性质。
  6. content-available:此键可用于发送静默推送通知。
  7. mutable-content:此键可用于在显示通知之前修改通知。我们可以通过将其设置为 1 来实现。

我们也可以在通知负载中添加自定义数据。但是,它不应超过 4096 字节。

推送通知处理

iOS 会根据应用程序的状态调用 AppDelegate 的不同方法(当用户点击通知时)。

我们需要在 AppDelegate 中设置 UNUserNotificationCenterDelegate 并实现委托方法,即 willPresent 和 didRecieve。

将以下代码行添加到 application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) 方法。

现在,我们已经完成了设置代理,我们可以实现代理方法。在 AppDelegate 的末尾添加以下代码。

第一个委托方法,即 willPresent,在通知到达应用程序时被调用。但是,当用户点击通知时,将调用第二个委托方法,即 didRecieve。

我们可以在 didRecieve 委托方法中检查应用程序的当前状态,并根据应用程序的当前状态执行操作。为此,请用以下代码替换 didRecieve 的代码。

但是,如果应用程序未运行且通知到达,则会调用 AppDelegate 中的 application(_:didFinishLaunchingWithOptions: ) 方法。

同时,让我们通过添加一个带有 Home 和 Notifications 两个标签栏项的 UITabBarController 来配置我们的应用程序 APNS。让我们在 Home 中添加一个 webview,并在用户点击通知时尝试导航到 Notifications。

现在,让我们在应用程序中测试推送通知并尝试检索数据。

运行应用程序并再次使用终端发送模拟推送通知。将应用程序保持在前台,看看推送通知是否到达。它应该如下图所示。

Push Notifications in iOS

现在,在 didReceive 委托方法中添加一个断点,并尝试在控制台中打印通知内容。我们应该在控制台中看到以下结果。

但是,我们可以传递这些数据并将通知显示在 Notifications Tab 中。另外,如果应用程序未运行,我们也应该在 AppDelegate 的 didFinishLaunchingWithOptions(: ) 方法中添加通知处理代码。