教程:使用 Azure 通知中心向 iOS 应用发送推送通知Tutorial: Send push notifications to iOS apps using Azure Notification Hubs

在本教程中,你将使用 Azure 通知中心向 iOS 应用程序发送推送通知。In this tutorial, you use Azure Notification Hubs to send push notifications to an iOS application. 你将创建一个空白 iOS 应用,它使用 Apple Push Notification 服务 (APNs) 接收推送通知。You create a blank iOS app that receives push notifications by using the Apple Push Notification service (APNs).

在本教程中,你将执行以下步骤:In this tutorial, you take the following steps:

  • 生成证书签名请求文件Generate the certificate signing request file
  • 请求你的应用推送通知Request your app for push notifications
  • 为应用程序创建配置文件Create a provisioning profile for the app
  • 针对 iOS 推送通知配置通知中心Configure your notification hub for iOS push notifications
  • 将 iOS 应用连接到通知中心Connect your iOS app to notification hubs
  • 发送测试推送通知Send test push notifications
  • 验证应用可以接收通知Verify that your app receives notifications

可以在 GitHub 上找到本教程的已完成代码。The complete code for this tutorial can be found on GitHub.

先决条件Prerequisites

若要完成本教程,需要满足以下先决条件:To complete this tutorial, you need the following prerequisites:

完成本教程是学习有关 iOS 应用的所有其他通知中心教程的先决条件。Completing this tutorial is a prerequisite for all other Notification Hubs tutorials for iOS apps.

生成证书签名请求文件Generate the certificate-signing request file

Apple Push Notification 服务 (APNs) 使用证书对推送通知进行身份验证。The Apple Push Notification Service (APNs) uses certificates to authenticate your push notifications. 请遵照这些说明来创建用于发送和接收通知的所需推送证书。Follow these instructions to create the necessary push certificate to send and receive notifications. 有关这些概念的详细信息,请参阅正式的 Apple Push Notification 服务文档。For more information on these concepts, see the official Apple Push Notification Service documentation.

生成证书签名请求 (CSR) 文件,Apple 将使用该文件生成签名的推送证书。Generate the Certificate Signing Request (CSR) file, which Apple uses to generate a signed push certificate.

  1. 在 Mac 上,运行 Keychain Access 工具。On your Mac, run the Keychain Access tool. 可以从启动台上的“Utilities”或“Other”文件夹中打开该工具。 It can be opened from the Utilities folder or the Other folder on the Launchpad.

  2. 选择“Keychain Access”,展开“Certificate Assistant”(证书助理),然后选择“Request a Certificate from a Certificate Authority”(从证书颁发机构请求证书)。 Select Keychain Access, expand Certificate Assistant, and then select Request a Certificate from a Certificate Authority.

    使用 Keychain Access 请求新证书

    备注

    默认情况下,Keychain Access 选择列表中的第一项。By default, Keychain Access selects the first item in the list. 如果你位于“Certificates”(证书) 类别中,并且“Apple Worldwide Developer Relations Certification Authority”(Apple 全球开发者关系证书颁发机构) 不是列表中的第一项,这可能会是个问题。This can be a problem if you're in the Certificates category and Apple Worldwide Developer Relations Certification Authority is not the first item in the list. 在生成 CSR(证书签名请求)之前,请确保已有非密钥项,或者已选择“Apple Worldwide Developer Relations Certification Authority”(Apple 全球开发者关系证书颁发机构) 密钥。Make sure you have a non-key item, or the Apple Worldwide Developer Relations Certification Authority key is selected, before generating the CSR (Certificate Signing Request).

  3. 选择“User Email Address”(用户电子邮件地址),输入“Common Name”(公用名)值,确保指定“Saved to disk”(保存到磁盘),然后选择“Continue”(继续)。 Select your User Email Address, enter your Common Name value, make sure that you specify Saved to disk, and then select Continue. 将“CA Email Address”(CA 电子邮件地址)留空,因为它不是必填字段 。Leave CA Email Address blank as it isn't required.

    所需证书信息

  4. 在“Save As”(另存为)中为 CSR 文件输入一个名称,在“Where”(位置)中选择位置,然后选择“Save”(保存)。 Enter a name for the CSR file in Save As, select the location in Where, and then select Save.

    为证书选择一个文件名

    此操作会将 CSR 文件保存到选定位置。This action saves the CSR file in the selected location. 默认位置为“桌面”。 The default location is Desktop. 请记住为此文件选择的位置。Remember the location chosen for the file.

接下来,向 Apple 注册应用,启用推送通知并上传导出的 CSR,以便创建推送证书。Next, register your app with Apple, enable push notifications, and upload the exported CSR to create a push certificate.

为推送通知注册应用程序Register your app for push notifications

若要将推送通知发送到 iOS 应用,请向 Apple 注册应用程序,还要注册推送通知。To send push notifications to an iOS app, register your application with Apple, and also register for push notifications.

  1. 如果尚未注册应用,请浏览到 Apple 开发人员中心的 iOS 预配门户If you haven't already registered your app, browse to the iOS Provisioning Portal at the Apple Developer Center. 使用你的 Apple ID 登录到门户,然后选择“标识符” 。Sign in to the portal with your Apple ID, and select Identifiers. 然后选择 + 注册新应用。Then select + to register a new app.

    iOS 预配门户应用 ID 页

  2. 在“注册新的标识符” 屏幕上,选择“应用 ID” 单选按钮。On the Register a New Identifier screen, select the App IDs radio button. 然后选择“继续”。 Then select Continue.

    iOS 预配门户“注册新 ID”页

  3. 更新新应用的以下三个值,然后选择“Continue”(继续): Update the following three values for your new app, and then select Continue:

    • 说明:键入应用的描述性名称。Description: Type a descriptive name for your app.

    • 捆绑 ID:按应用分发指南中所述,输入格式为 Organization Identifier.Product Name 的捆绑 ID。Bundle ID: Enter a Bundle ID of the form Organization Identifier.Product Name as mentioned in the App Distribution Guide. “Organization Identifier”(组织标识符)和“Product Name”(产品名称)值必须与创建 Xcode 项目时使用的组织标识符与产品名称匹配。 The Organization Identifier and Product Name values must match the organization identifier and product name you use when you create your Xcode project. 在下面的屏幕截图中,NotificationHubs 值用作组织标识符,GetStarted 值用作产品名称。In the following screenshot, the NotificationHubs value is used as an organization identifier and the GetStarted value is used as the product name. 确保“Bundle Identifier”(捆绑标识符)值与 Xcode 项目中的值匹配,这样 Xcode 就可以使用正确的发布配置文件。 Make sure the Bundle Identifier value matches the value in your Xcode project, so that Xcode uses the correct publishing profile.

      iOS 预配门户“注册应用 ID”页

    • Push Notifications(推送通知):在“Capabilities”(功能)部分选中“Push Notifications”(推送通知)选项 。Push Notifications: Check the Push Notifications option in the Capabilities section.

      用于注册新应用 ID 的窗体

      此操作会生成应用 ID 并请求你确认信息。This action generates your App ID and requests that you confirm the information. 选择“Continue”(继续),然后选择“Register”(注册) 以确认新的应用 ID。Select Continue, then select Register to confirm the new App ID.

      确认新的应用 ID

      选择“Register”(注册) 后,新的应用 ID 将作为行项出现在“Certificates, Identifiers & Profiles”(证书、标识符和配置文件) 页中。After you select Register, you see the new App ID as a line item in the Certificates, Identifiers & Profiles page.

  4. 在“Certificates, Identifiers & Profiles”(证书、标识符和配置文件) 页的“Identifiers”(标识符) 下,找到你刚刚创建的应用 ID 行项,并选择其所在的行以显示“Edit your App ID Configuration”(编辑应用 ID 配置) 屏幕。In the Certificates, Identifiers & Profiles page, under Identifiers, locate the App ID line item that you just created, and select its row to display the Edit your App ID Configuration screen.

  5. 向下滚动到选中的“Push Notifications”(推送通知) 选项,然后选择“Configure”(配置) 以创建证书。Scroll down to the checked Push Notifications option, and then select Configure to create the certificate.

    编辑应用 ID 页

  6. 此时将显示“Apple Push Notification service SSL Certificates”(Apple 推送通知服务 SSL 证书) 窗口。The Apple Push Notification service SSL Certificates window appears. 选择“Development SSL Certificate”(开发 SSL 证书) 部分下的“Create Certificate”(创建证书) 按钮。Select the Create Certificate button under the Development SSL Certificate section.

    “为应用 ID 创建证书”按钮

    此时将显示“Create a new Certificate”(创建新证书) 屏幕。The Create a new Certificate screen is displayed.

    备注

    本教程使用开发证书。This tutorial uses a development certificate. 注册生产证书时使用相同的过程。The same process is used when registering a production certificate. 只需确保在发送通知时使用相同的证书类型。Just make sure that you use the same certificate type when sending notifications.

  7. 选择“Choose File”(选择文件),浏览到在第一个任务中保存 CSR 文件的位置,然后双击证书名以加载该证书。 Select Choose File, browse to the location where you saved the CSR file from the first task, and then double-click the certificate name to load it. 然后选择“继续”。 Then select Continue.

  8. 当门户创建证书后,请选择“Download”(下载)按钮。 After the portal creates the certificate, select the Download button. 保存证书,并记住保存证书的位置。Save the certificate, and remember the location to which it's saved.

    已生成证书的下载页

    这将下载证书并将其保存到计算机的 Downloads 文件夹。The certificate is downloaded and saved to your computer in your Downloads folder.

    在 Downloads 文件夹中找到证书文件

    备注

    默认情况下,下载的开发证书名为 aps_development.cerBy default, the downloaded development certificate is named aps_development.cer.

  9. 双击下载的推送证书 aps_development.cerDouble-click the downloaded push certificate aps_development.cer. 此操作将在密钥链中安装新证书,如下图所示:This action installs the new certificate in the Keychain, as shown in the following image:

    Keychain Access 证书列表,显示了新证书

    备注

    证书中的名称可能会不同,但会以 Apple Development iOS Push Services 作为前缀。Although the name in your certificate might be different, the name will be prefixed with Apple Development iOS Push Services.

  10. 在 Keychain Access 中,右键单击在“Certificates”(证书)类别中创建的新推送证书 。In Keychain Access, right-click the new push certificate that you created in the Certificates category. 选择“Export”(导出),为文件命名,选择“.p12”格式,并选择“Save”(保存)。 Select Export, name the file, select the .p12 format, and then select Save.

    将证书作为 p12 格式导出

    可以选择使用密码保护证书,但这是可选的。You can choose to protect the certificate with a password, but this is optional. 如果要跳过密码创建,请单击“OK”(确定) 。Click OK if you want to bypass password creation. 记下导出的 .p12 证书的文件名和位置。Make a note of the file name and location of the exported .p12 certificate. 它们用于启用 APNs 身份验证。They are used to enable authentication with APNs.

    备注

    你的 .p12 文件名和位置可能不同于本教程中所示的名称和位置。Your .p12 file name and location might be different than what is pictured in this tutorial.

为应用程序创建配置文件Create a provisioning profile for the app

  1. 返回到 iOS 预配门户,选择“Certificates, Identifiers & Profiles”(证书、标识符和配置文件) ,从左侧菜单中选择“Profiles”(配置文件) ,然后选择 + 创建新的配置文件。Return to the iOS Provisioning Portal, select Certificates, Identifiers & Profiles, select Profiles from the left menu, and then select + to create a new profile. 此时将显示“Register a New Provisioning Profile”(注册新的预配配置文件) 屏幕。The Register a New Provisioning Profile screen appears.

  2. 选择“Development”(开发)下的“iOS App Development”(iOS 应用程序开发)作为预配配置文件类型,然后选择“Continue”(继续)。 Select iOS App Development under Development as the provisioning profile type, and then select Continue.

    预配配置文件列表

  3. 接下来,从“App ID”(应用 ID)下拉列表中选择创建的应用 ID,然后选择“Continue”(继续)。 Next, select the app ID you created from the App ID drop-down list, and select Continue.

    选择应用 ID

  4. 在“Select certificates”(选择证书)窗口中,选择用于代码签名的开发证书,然后选择“Continue”(继续)。 In the Select certificates window, select the development certificate that you use for code signing, and select Continue. 此证书不是所创建的推送证书。This certificate isn't the push certificate you created. 如果不存在,则必须创建一个。If one does not exist, you must create it. 如果证书存在,请跳到下一步。If a certificate does exist, skip to the next step. 若要创建开发证书(如果开发证书不存在),请执行以下操作:To create a development certificate if one does not exist:

    1. 如果看到“No Certificates are available”(没有可用的证书) ,请选择“Create Certificate”(创建证书) 。If you see No Certificates are available, select Create Certificate.
    2. 在“Software”(软件) 部分中,选择“Apple Development”(Apple 开发) 。In the Software section, select Apple Development. 然后选择“继续”。 Then select Continue.
    3. 在“Create a new Certificate”(创建新证书) 屏幕中,选择“Choose File”(选择文件) 。In the Create a New Certificate screen, select Choose File.
    4. 浏览到之前创建的“Certificate Signing Request”(证书签名请求) 证书,选择该证书,然后选择“Open”(打开) 。Browse to the Certificate Signing Request certificate you created earlier, select it, and then select Open.
    5. 选择“继续”。 Select Continue.
    6. 下载开发证书,并记住其保存位置。Download the development certificate, and remember the location to which it's saved.
  5. 返回到“Certificates, Identifiers & Profiles”(证书、标识符和配置文件) 页,从左侧菜单中选择“Profiles”(配置文件) ,然后选择 + 创建新的配置文件。Return to the Certificates, Identifiers & Profiles page, select Profiles from the left menu, and then select + to create a new profile. 此时将显示“Register a New Provisioning Profile”(注册新的预配配置文件) 屏幕。The Register a New Provisioning Profile screen appears.

  6. 在“Select certificates”(选择证书)窗口中,选择你刚刚创建的开发证书。 In the Select certificates window, select the development certificate that you just created. 然后选择“继续”。 Then select Continue.

  7. 接下来,选择用于测试的设备,然后选择“Continue”(继续)。 Next, select the devices to use for testing, and select Continue.

  8. 最后,在“Provisioning Profile Name”(预配配置文件名称)中为概要文件选择一个名称,然后选择“Generate”(生成)。 Finally, choose a name for the profile in Provisioning Profile Name, and select Generate.

    选择预配配置文件名称

  9. 创建了新的预配配置文件后,选择“Download”(下载) 。When the new provisioning profile is created, select Download. 记住保存证书的位置。Remember the location to which it's saved.

  10. 浏览到预配配置文件所在的位置,然后双击该配置文件以将其安装在 Xcode 开发计算机上。Browse to the location of the provisioning profile, and then double-click it to install it on your Xcode development machine.

创建通知中心Create a notification hub

在本部分,我们创建一个通知中心,并使用以前创建的 .p12 推送证书配置 APNs 身份验证。In this section, you create a notification hub and configure authentication with APNs by using the .p12 push certificate that you previously created. 如果想要使用已创建的通知中心,可以跳到步骤 5。If you want to use a notification hub that you've already created, you can skip to step 5.

  1. 登录到 Azure 门户Sign in to the Azure portal.

  2. 在左侧菜单上选择“所有服务” ,然后在“移动”部分中选择“通知中心”。 Select All services on the left menu, and then select Notification Hubs in the Mobile section. 选择服务名称旁边的星形图标,以便将服务添加到左侧菜单上的“收藏夹”部分。 Select the star icon next to the service name to add the service to the FAVORITES section on the left menu. 在将“通知中心” 添加到“收藏夹” 之后,在左侧菜单上选择它。After you add Notification Hubs to FAVORITES, select it on the left menu.

    Azure 门户 - 选择“通知中心”

  3. 在“通知中心” 页面上,在工具栏上选择“添加” 。On the Notification Hubs page, select Add on the toolbar.

    通知中心 -“添加”工具栏按钮

  4. 在“通知中心” 页面上,执行以下步骤:On the Notification Hub page, do the following steps:

    1. 将一个名称输入“通知中心”。 Enter a name in Notification Hub.

    2. 在“创建新的命名空间”中输入名称。 Enter a name in Create a new namespace. 命名空间包含一个或多个中心。A namespace contains one or more hubs.

    3. 从“位置”下拉列表框中选择值。 Select a value from the Location drop-down list box. 此值指定要在其中创建通知中心的位置。This value specifies the location in which you want to create the hub.

    4. 在“资源组”中选择现有的资源组,或者为新资源组创建一个名称。 Select an existing resource group in Resource Group, or create a name for a new resource group.

    5. 选择“创建” 。Select Create.

      Azure 门户 - 设置通知中心属性

  5. 选择“通知”(钟形图标),然后选择“转到资源” 。Select Notifications (the bell icon), and then select Go to resource. 还可以刷新“通知中心” 页上的列表,然后选择通知中心。You can also refresh the list on the Notification Hubs page and select your hub.

    Azure 门户 - 通知 -> 转到资源

  6. 从列表中选择“访问策略” 。Select Access Policies from the list. 记下向你提供的两个连接字符串。Note that the two connection strings are available to you. 稍后在处理推送通知时需要它们。You'll need them later to handle push notifications.

    重要

    请勿 在应用程序中使用 DefaultFullSharedAccessSignature 策略。Do not use the DefaultFullSharedAccessSignature policy in your application. 这只能在后端使用。This is meant to be used in your back end only.

    Azure 门户 - 通知中心连接字符串

使用 APNs 信息配置通知中心Configure your notification hub with APNs information

  1. 在“通知服务”下选择“Apple (APNS)”。 Under Notification Services, select Apple (APNS).

  2. 选择“证书”。 Select Certificate.

  3. 选择文件图标。Select the file icon.

  4. 选择前面导出的 .p12 文件,然后选择“Open”(打开) 。Select the .p12 file that you exported earlier, and then select Open.

  5. 如果需要,请指定正确的密码。If required, specify the correct password.

  6. 选择“沙盒” 模式。Select Sandbox mode. 仅当希望将推送通知发送给从应用商店购买应用的用户时,才应使用“生产”模式。 Use the Production mode only if you want to send push notifications to users who purchased your app from the store.

    在 Azure 门户中配置 APNs 证书

  7. 选择“保存” 。Select Save.

现在已使用 APNs 配置通知中心。You've now configured your notification hub with APNs. 此外还有了用于注册应用和发送推送通知的连接字符串。You also have the connection strings to register your app and send push notifications.

将 iOS 应用连接到通知中心Connect your iOS app to Notification Hubs

  1. 在 Xcode 中,创建新的 iOS 项目,然后选择“单视图应用程序”模板 。In Xcode, create a new iOS project and select the Single View Application template.

    Xcode — 单一视图应用程序

  2. 设置新项目的选项时,请务必使用在 Apple 开发人员门户中设置捆绑标识符时使用的同一产品名称组织标识符When setting the options for your new project, make sure to use the same Product Name and Organization Identifier that you used when you set the bundle identifier in the Apple Developer portal.

  3. 在“项目导航器”的“目标”下选择项目名称,然后选择“签名和功能”选项卡 。确保为 Apple 开发人员帐户选择适当的“团队” 。Under Project Navigator, select your project name under Targets, then select the Signing & Capabilities tab. Make sure you select the appropriate Team for your Apple Developer account. XCode 会根据捆绑标识符自动下拉以前创建的预配配置文件。XCode should automatically pull down the Provisioning Profile you created previously based on your bundle identifier.

    如果屏幕未显示在 Xcode 中创建的新预配配置文件,请尝试刷新签名标识的配置文件。If you don't see the new provisioning profile that you created in Xcode, try refreshing the profiles for your signing identity. 单击菜单栏上的“Xcode”,再依次单击“首选项”、“帐户”选项卡、“查看详细信息”按钮、你的签名标识,然后单击右下角的刷新按钮 。Click Xcode on the menu bar, click Preferences, click the Account tab, click the View Details button, click your signing identity, and then click the refresh button in the bottom-right corner.

    Xcode — 预配配置文件

  4. 在“签名和功能”选项卡中,选择“+ 功能” 。In the Signing & Capabilities tab, select + Capability. 双击“推送通知”以启用它 。Double-click Push Notifications to enable it.

    Xcode - 推送功能

  5. 添加 Azure 通知中心 SDK 模块。Add the Azure Notification Hubs SDK modules.

    可以在应用中集成 Azure 通知中心 SDK,方法是使用 Cocoapods 或者手动将二进制文件添加到项目。You can integrate the Azure Notification Hubs SDK in your app by using Cocoapods or by manually adding the binaries to your project.

    • 通过 Cocoapods 进行集成Integration via Cocoapods

      将以下依赖项添加到 podfile,以便将 Azure 通知中心 SDK 包括到应用中。Add the following dependencies to your podfile to include Azure Notification Hubs SDK into your app.

      pod 'AzureNotificationHubs-iOS'
      

      运行 pod install,以便安装新定义的 Pod 并打开 .xcworkspaceRun pod install to install your newly defined pod and open your .xcworkspace.

      备注

      如果在运行 pod install 时看到错误(例如 [!] 找不到 AzureNotificationHubs-iOS 的规范 ),请运行 pod repo update 以从 Cocoapods 存储库获取最新的 pod,然后运行 pod installIf you see an error such as [!] Unable to find a specification for AzureNotificationHubs-iOS while running pod install, please run pod repo update to get the latest pods from the Cocoapods repository, and then run pod install.

    • 通过 Carthage 进行集成Integration via Carthage

      将以下依赖项添加到 Cartfile,以便将 Azure 通知中心 SDK 包括到应用中。Add the following dependencies to your Cartfile to include Azure Notification Hubs SDK into your app.

      github "Azure/azure-notificationhubs-ios"
      

      接下来,更新并生成依赖项:Next, update, and build dependencies:

      $ carthage update
      

      有关如何使用 Carthage 的详细信息,请参阅 Carthage GitHub 存储库For more information about using Carthage, see the Carthage GitHub repository.

    • 通过将二进制文件复制到项目中进行集成Integration by copying the binaries into your project

      1. 下载以 zip 文件形式提供的 Azure 通知中心 SDK 框架,然后将其解压缩。Download the Azure Notification Hubs SDK framework provided as a zip file and unzip it.

      2. 在 Xcode 中,右键单击项目,然后单击“将文件添加到”选项,将 WindowsAzureMessaging.framework 文件夹添加到 Xcode 项目 。In Xcode, right-click your project and click the Add Files to option to add the WindowsAzureMessaging.framework folder to your Xcode project. 选择“选项”,确保选中“根据需要复制项目”,然后单击“添加”。 Select Options and make sure Copy items if needed is selected, and then click Add.

        解压缩 Azure SDK

  6. 将新的头文件添加到名为 Constants.h 的项目。Add a new header file to your project named Constants.h. 为此,请右键单击项目名称并选择“新建文件...” 。然后选择“头文件” 。To do so, right-click the project name and select New File.... Then select Header File. 此文件保存着通知中心的常量。This file holds the constants for your notification hub. 然后,选择“下一步” 。Then select Next. 将文件命名为 Constants.hName the file Constants.h.

  7. 将以下代码添加到 Constants.h 文件中:Add the following code to the Constants.h file:

    #ifndef Constants_h
    #define Constants_h
    
    extern NSString* const NHInfoConnectionString;
    extern NSString* const NHInfoHubName;
    extern NSString* const NHUserDefaultTags;
    
    #endif /* Constants_h */
    
  8. 添加 Constants.h 的实现文件。Add the implementation file for Constants.h. 为此,请右键单击项目名称并选择“新建文件...” 。选择“Objective-C 文件”,然后选择“下一步” 。To do so, right-click the project name and select New File.... Select Objective-C File, and then select Next. 将文件命名为 Constants.mName the file Constants.m.

    添加 .m 文件

  9. 打开 Constants.m 文件并将其内容替换为以下代码。Open the Constants.m file and replace its contents with the following code. 将字符串文本占位符 NotificationHubConnectionStringNotificationHubConnectionString 分别替换为之前从门户中获取的中心名称和 DefaultListenSharedAccessSignatureReplace the string literal placeholders NotificationHubConnectionString and NotificationHubConnectionString with the hub name and the DefaultListenSharedAccessSignature, respectively, as you previously obtained from the portal:

    #import <Foundation/Foundation.h>
    #import "Constants.h"
    
    NSString* const NHInfoConnectionString = @"NotificationHubConnectionString";
    NSString* const NHInfoHubName = @"NotificationHubName";
    NSString* const NHUserDefaultTags = @"notification_tags";
    
  10. 打开项目的 AppDelegate.h 文件,并将其内容替换为以下代码:Open your project's AppDelegate.h file and replace its contents with the following code:

    #import <UIKit/UIKit.h>
    #import <WindowsAzureMessaging/WindowsAzureMessaging.h>
    #import <UserNotifications/UserNotifications.h> 
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
    
    @property (strong, nonatomic) UIWindow *window;
    
    - (void)handleRegister;
    - (void)handleUnregister;
    
    @end
    
    
  11. 在项目的 AppDelegate.m 文件中,添加以下 import 语句:In the project's AppDelegate.m file, add the following import statements:

    #import "Constants.h"
    #import "NotificationDetailViewController.h"
    
  12. 此外,在 AppDelegate.m 文件中,根据 iOS 版本在 didFinishLaunchingWithOptions 方法中添加以下代码行。Also in your AppDelegate.m file, add the following line of code in the didFinishLaunchingWithOptions method based on your version of iOS. 此代码向 APNs 注册设备句柄:This code registers your device handle with APNs:

    [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
    
  13. 在同一 AppDelegate.m 文件中,将 didFinishLaunchingWithOptions 后面的所有代码替换为以下代码:In the same AppDelegate.m file, replace all the code after didFinishLaunchingWithOptions with the following code:

    // Tells the app that a remote notification arrived that indicates there is data to be fetched.
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
        NSLog(@"Received remote (silent) notification");
        [self logNotificationDetails:userInfo];
    
        //
        // Let the system know the silent notification has been processed.
        //
        completionHandler(UIBackgroundFetchResultNoData);
    }
    
    // Tells the delegate that the app successfully registered with Apple Push Notification service (APNs).
    
    - (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        NSMutableSet *tags = [[NSMutableSet alloc] init];
    
        // Load and parse stored tags
        NSString *unparsedTags = [[NSUserDefaults standardUserDefaults] valueForKey:NHUserDefaultTags];
        if (unparsedTags.length > 0) {
            NSArray *tagsArray = [unparsedTags componentsSeparatedByString: @","];
            [tags addObjectsFromArray:tagsArray];
        }
    
        // Register the device with the Notification Hub.
        // If the device has not already been registered, this will create the registration.
        // If the device has already been registered, this will update the existing registration.
        //
        SBNotificationHub* hub = [self getNotificationHub];
        [hub registerNativeWithDeviceToken:deviceToken tags:tags completion:^(NSError* error) {
            if (error != nil) {
                NSLog(@"Error registering for notifications: %@", error);
            } else {
                [self showAlert:@"Registered" withTitle:@"Registration Status"];
            }
        }];
    }
    
    // UNUserNotificationCenterDelegate methods
    //
    // Asks the delegate how to handle a notification that arrived while the app was running in the  foreground.
    
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
        NSLog(@"Received notification while the application is in the foreground");
    
        // The system calls this delegate method when the app is in the foreground. This allows the app to handle the notification
        // itself (and potentially modify the default system behavior).
    
        // Handle the notification by displaying custom UI.
        //
        [self showNotification:notification.request.content.userInfo];
    
        // Use 'options' to specify which default behaviors to enable.
        // - UNAuthorizationOptionBadge: Apply the notification's badge value to the app�s icon.
        // - UNAuthorizationOptionSound: Play the sound associated with the notification.
        // - UNAuthorizationOptionAlert: Display the alert using the content provided by the notification.
        //
        // In this case, do not pass UNAuthorizationOptionAlert because the notification was handled by the app.
        //
        completionHandler(UNAuthorizationOptionBadge | UNAuthorizationOptionSound);
    }
    
    // Asks the delegate to process the user's response to a delivered notification.
    //
    
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
        NSLog(@"Received notification while the application is in the background");
    
        // The system calls this delegate method when the user taps or responds to the system notification.
    
        // Handle the notification response by displaying custom UI
        //
        [self showNotification:response.notification.request.content.userInfo];
    
        // Let the system know the response has been processed.
        //
        completionHandler();
    }
    
    // App logic and helpers
    
    - (SBNotificationHub *)getNotificationHub {
        NSString *hubName = [[NSBundle mainBundle] objectForInfoDictionaryKey:NHInfoHubName];
        NSString *connectionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:NHInfoConnectionString];
    
        return [[SBNotificationHub alloc] initWithConnectionString:connectionString notificationHubPath:hubName];
    }
    
    - (void)handleRegister {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    
        UNAuthorizationOptions options =  UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
        [center requestAuthorizationWithOptions:(options) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (error != nil) {
                NSLog(@"Error requesting for authorization: %@", error);
            }
        }];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    
    - (void)handleUnregister {
        //
        // Unregister the device with the Notification Hub.
        //
        SBNotificationHub *hub = [self getNotificationHub];
        [hub unregisterNativeWithCompletion:^(NSError* error) {
            if (error != nil) {
                NSLog(@"Error unregistering for push: %@", error);
            } else {
                [self showAlert:@"Unregistered" withTitle:@"Registration Status"];
            }
        }];
    }
    
    - (void)logNotificationDetails:(NSDictionary *)userInfo {
        if (userInfo != nil) {
            UIApplicationState state = [UIApplication sharedApplication].applicationState;
            BOOL background = state != UIApplicationStateActive;
            NSLog(@"Received %@notification: \n%@", background ? @"(background) " : @"", userInfo);
        }
    }
    
    - (void)showAlert:(NSString *)message withTitle:(NSString *)title {
        if (title == nil) {
            title = @"Alert";
        }
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
        [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alert animated:YES completion:nil];
    }
    
    - (void)showNotification:(NSDictionary *)userInfo {
        [self logNotificationDetails:userInfo];
    
        NotificationDetailViewController *notificationDetail = [[NotificationDetailViewController alloc] initWithUserInfo:userInfo];
        [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:notificationDetail animated:YES completion:nil];
    }
    
    @end
    

    此代码使用在 Constants.h 中指定的连接信息连接到通知中心。This code connects to the notification hub using the connection information you specified in Constants.h. 然后,它向通知中心提供设备令牌,使通知中心能够发送通知。It then gives the device token to the notification hub so that the notification hub can send notifications.

NotificationDetailViewControllerNotificationDetailViewController

  1. 与之前的说明类似,添加另一个名为 NotificationDetailViewController.h 的头文件。Similar the previous instructions, add another header file named NotificationDetailViewController.h. 将新的头文件的内容替换为以下代码:Replace the contents of the new header file with the following code:

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NotificationDetailViewController : UIViewController
    
    @property (strong, nonatomic) IBOutlet UILabel *titleLabel;
    @property (strong, nonatomic) IBOutlet UILabel *bodyLabel;
    @property (strong, nonatomic) IBOutlet UIButton *dismissButton;
    
    @property (strong, nonatomic) NSDictionary *userInfo;
    
    - (id)initWithUserInfo:(NSDictionary *)userInfo;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
  2. 添加实现文件 NotificationDetailViewController.mAdd the implementation file NotificationDetailViewController.m. 将该文件的内容替换为以下代码,其实现 UIViewController 方法:Replace the contents of the file with the following code, which implements the UIViewController methods:

    #import "NotificationDetailViewController.h"
    
    @interface NotificationDetailViewController ()
    
    @end
    
    @implementation NotificationDetailViewController
    
    - (id)initWithUserInfo:(NSDictionary *)userInfo {
        self = [super initWithNibName:@"NotificationDetail" bundle:nil];
        if (self) {
            _userInfo = userInfo;
        }
        return self;
    }
    
    - (void)viewDidLayoutSubviews {
        [self.titleLabel sizeToFit];
        [self.bodyLabel sizeToFit];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSString *title = nil;
        NSString *body = nil;
    
        NSDictionary *aps = [_userInfo valueForKey:@"aps"];
        NSObject *alertObject = [aps valueForKey:@"alert"];
        if (alertObject != nil) {
            if ([alertObject isKindOfClass:[NSDictionary class]]) {
                NSDictionary *alertDict = (NSDictionary *)alertObject;
                title = [alertDict valueForKey:@"title"];
                body = [alertObject valueForKey:@"body"];
            } else if ([alertObject isKindOfClass:[NSString class]]) {
                body = (NSString *)alertObject;
            } else {
                NSLog(@"Unable to parse notification content. Unexpected format: %@", alertObject);
            }
        }
    
        if (title == nil) {
            title = @"<unset>";
        }
    
        if (body == nil) {
            body = @"<unset>";
        }
    
        self.titleLabel.text = title;
        self.bodyLabel.text = body;
    }
    
    - (IBAction)handleDismiss:(id)sender {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    @end
    

ViewControllerViewController

  1. 在项目的 ViewController.h 文件中,添加以下 import 语句:In the project's ViewController.h file, add the following import statements:

    #import <WindowsAzureMessaging/WindowsAzureMessaging.h>
    #import <UserNotifications/UserNotifications.h>
    
  2. 此外,在 ViewController.h 中,在 @interface 声明后添加以下属性声明:Also in ViewController.h, add the following property declarations after the @interface declaration:

    @property (strong, nonatomic) IBOutlet UITextField *tagsTextField;
    @property (strong, nonatomic) IBOutlet UIButton *registerButton;
    @property (strong, nonatomic) IBOutlet UIButton *unregisterButton;
    
  3. 在项目的 ViewController.m 实现文件中,将该文件的内容替换为以下代码:In the project's ViewController.m implementation file, replace the contents of the file with the following code:

    #import "ViewController.h"
    #import "Constants.h"
    #import "AppDelegate.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    // UIViewController methods
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        // Simple method to dismiss keyboard when user taps outside of the UITextField.
        [self.view endEditing:YES];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // Load raw tags text from storage and initialize the text field
        self.tagsTextField.text = [[NSUserDefaults standardUserDefaults] valueForKey:NHUserDefaultTags];
    }
    
    - (IBAction)handleRegister:(id)sender {
        // Save raw tags text in storage
        [[NSUserDefaults standardUserDefaults] setValue:self.tagsTextField.text forKey:NHUserDefaultTags];
    
    // Delegate processing the register action to the app delegate.
    [[[UIApplication sharedApplication] delegate] performSelector:@selector(handleRegister)];
    }
    
    - (IBAction)handleUnregister:(id)sender {
        [[[UIApplication sharedApplication] delegate] performSelector:@selector(handleUnregister)];
    }
    
    @end
    
  4. 若要验证是否没有故障,请在设备上生成并运行应用。To verify there are no failures, build and run the app on your device.

发送测试推送通知Send test push notifications

可以在 Azure 门户中使用“测试性发送”选项,在应用中测试通知的发送。You can test receiving notifications in your app with the Test Send option in the Azure portal. 它会向设备发送测试性的推送通知。It sends a test push notification to your device.

Azure 门户 - 测试性发送

通常,推送通知是在后端服务(例如,Mobile Apps,或者使用兼容库的 ASP.NET)中发送的。Push notifications are normally sent in a back-end service like Mobile Apps or ASP.NET using a compatible library. 如果后端没有可用库,也可使用 REST API 直接发送通知消息。If a library isn't available for your back end, you can also use the REST API directly to send notification messages.

下面是可能需要查看的有关发送通知的其他教程列表:Here is a list of some other tutorials you might want to review for sending notifications:

验证应用可以接收推送通知Verify that your app receives push notifications

要在 iOS 上测试推送通知,必须将应用部署到物理 iOS 设备。To test push notifications on iOS, you must deploy the app to a physical iOS device. 不能使用 iOS 模拟器发送 Apple 推送通知。You cannot send Apple push notifications by using the iOS Simulator.

  1. 运行应用并验证注册是否成功,然后按“确定” 。Run the app and verify that registration succeeds, and then press OK.

    iOS 应用推送通知注册测试

  2. 如上一部分所述,接下来可以从 Azure 门户发送测试推送通知。Next you send a test push notification from the Azure portal, as described in the previous section.

  3. 该推送通知会从特定通知中心发送到所有已注册为接收通知的设备。The push notification is sent to all devices that are registered to receive the notifications from the particular Notification Hub.

    iOS 应用推送通知接收测试

后续步骤Next steps

在这个简单的示例中,已将推送通知广播到所有已注册的 iOS 设备。In this simple example, you broadcasted push notifications to all your registered iOS devices. 若要了解如何向特定的 iOS 设备推送通知,请转到以下教程:To learn how to push notifications to specific iOS devices, advance to the following tutorial: