使用通知中心针对 Xamarin 应用发送 iOS 推送通知

概述

Important

若要完成本教程,你必须有一个有效的 Azure 帐户。如果你没有帐户,只需花费几分钟就能创建一个试用帐户。有关详细信息,请参阅 Azure 试用

本教程演示如何使用 Azure 通知中心将推送通知发送到 iOS 应用程序。 你将创建一个空白 Xamarin.iOS 应用,它使用 [Apple Push Notification 服务 APNs 接收推送通知。完成后,你将能够使用通知中心将推送通知广播到运行你的应用的所有设备。NotificationHubs 应用程序示例中提供了完成的代码。

本教程演示使用通知中心的简单推送消息广播方案。

先决条件

本教程需要的内容如下:

  • Xcode 6.0
  • iOS 7.0(或更高版本)兼容设备
  • iOS 开发人员计划成员身份
  • Xamarin Studio

    Note

    由于 iOS 推送通知配置要求,你必须在物理 iOS 设备(iPhone 或 iPad)而不是在模拟器上部署和测试示例应用程序。

只有在完成本教程后,才能完成有关 Xamarin iOS 应用的所有其他通知中心教程。

生成证书签名请求文件

Apple 推送通知服务 (APNS) 使用证书对推送通知进行身份验证。请遵照这些说明来创建用于发送和接收通知的所需推送证书。有关这些概念的详细信息,请参阅 Apple Push Notification 服务文档。

生成证书签名请求 (CSR) 文件,Apple 将使用该文件生成签名的推送证书。

  1. 在 Mac 上,运行 Keychain Access 工具。可以从启动板上的“Utilities”(实用工具)或“Other”(其他)文件夹中打开该工具。

  2. 单击“Keychain Access”,展开“Certificate Assistant”(证书助理),然后单击“Request a Certificate from a Certificate Authority...”(从证书颁发机构请求证书...)。

  3. 选择你的“User Email Address”(用户电子邮件地址)和“Common Name”(公用名),确保已选择“Saved to disk”(保存到磁盘),然后单击“Continue”(继续)。将“CA Email Address”(CA 电子邮件地址)字段保留空白,因为它不是必填字段。

  4. 在“Save As”(另存为)中为证书签名请求 (CSR) 文件键入一个名称,在“Where”(位置)中选择一个位置,然后单击“Save”(保存)。

    此操作会将 CSR 文件保存到选定位置;默认位置是桌面。请记住为此文件选择的位置。

接下来,你将要向 Apple 注册你的应用程序、启用推送通知并上载这个导出的 CSR 以创建一个推送证书。

为推送通知注册应用程序

若要将推送通知发送到 iOS 应用程序,你必须向 Apple 注册应用程序,还要注册推送通知。

  1. 如果你尚未注册应用程序,请导航到 Apple 开发人员中心的 iOS 设置门户,使用 Apple ID 登录,单击“Identifiers”(标识符),然后单击“App IDs”(应用程序 ID),最后单击“+”符号以注册新的应用程序。

  2. 更新新应用的以下三个字段,然后单击“Continue”(继续):

    • Name(名称):在“App ID Description”(应用 ID 说明)部分的“Name”(名称)字段中为应用键入一个描述性名称。

    • Bundle Identifier(捆绑标识符):在“Explicit App ID”(显式应用 ID)部分下,使用应用分发指南中所述的 <Organization Identifier>.<Product Name> 格式输入“Bundle Identifier”(捆绑标识符)。使用的“Organization Identifier”(组织标识符)和“Product Name”(产品名称)必须与你在创建 XCode 项目时要使用的组织标识符与产品名称匹配。在下面的屏幕截图中, NotificationHubs 用作组织标识符, GetStarted 用作产品名称。如果确保这些信息与你要在 XCode 项目中使用的值匹配,则就可以在 XCode 中使用正确的发布配置文件。

    • Push Notifications(推送通知):在“App Services”(应用服务)部分中选中“Push Notifications”(推送通知)选项。

      此时将会生成你的应用 ID 并请求你确认信息。单击“注册”以确认新的应用 ID。

      单击“注册”后,你将会看到如下所示的“注册已完成”屏幕。单击“Done”(完成)。

  3. 在开发人员中心的“App IDs”(应用 ID)下,找到你刚刚创建的应用 ID,然后单击其所在行。

    单击应用程序 ID 会显示应用程序详细信息。单击底部的“Edit”(编辑)按钮。

  4. 滚动到屏幕底部并单击“Development Push SSL Certificate”(开发推送 SSL 证书 )部分下的“Create Certificate...”(创建证书...)按钮。

    将显示“Add iOS Certificate”(添加 iOS 证书)助手。

    Note

    本教程使用开发证书。注册生产证书时使用相同的过程。你只需确保在发送通知时使用相同的证书类型。

  5. 单击“Choose File”(选择文件),浏览到你在第一个任务中创建的 CSR 文件保存到的位置,然后单击“Generate”(生成)。

  6. 门户创建证书之后,请单击“Download”(下载)按钮,然后单击“Done”(完成)。

    随后将会下载证书并将其保存到计算机上的 Downloads 文件夹。

    Note

    默认情况下,下载的文件(开发证书)名为 aps_development.cer

  7. 双击下载的推送证书 aps_development.cer

    将在 Keychain 中安装新证书,如下所示:

    Note

    证书中的名称可能不同,但将以 Apple Development iOS Push Services: 作为前缀。

  8. 在 Keychain Access 中,右键单击你在“Certificates”(证书)类别中创建的新推送证书。单击“导出”,为文件命名,选择“.p12”格式,然后单击“保存”。

    记下导出的 .p12 证书的文件名和位置。它将用于启用 APNS 身份验证。

    Note

    本教程将创建 QuickStart.p12 文件。你的文件名和位置可能不同。

为应用程序创建配置文件

  1. 返回 iOS 设置门户,选择“Provisioning Profiles”(设置配置文件),选择“All”(全部),然后单击“+”按钮创建一个新的配置文件。此时会启动“Add iOS Provisiong Profile”(添加 iOS 设置配置文件)向导

  2. 选择“Development”(开发)下的“iOS App Development”(iOS 应用程序开发)作为设置配置文件类型,然后单击“Continue”(继续)。

  3. 接下来,从“App ID”(应用程序 ID)下拉列表中选择你刚刚创建的应用程序 ID,然后单击“Continue”(继续)。

  4. 在“Select certificates”(选择证书)屏幕中,选择你经常用于代码签名的开发证书,然后单击“Continue”(继续)。这不是你刚刚创建的推送证书。

  5. 接下来,选择要用于测试的“Devices”(设备),然后单击“Continue”(继续)。

  6. 最后,在“Profile Name”(配置文件名称)中为配置文件选取一个名称,并单击“Generate”(生成)。

  7. 创建新的预配配置文件后,请单击下载该文件,并将其安装在你的 Xcode 开发计算机上。然后单击“Done”(完成)。

将你的应用连接到通知中心

创建新项目

  1. 在 Xamarin Studio 中,创建新的 iOS 项目,然后选择“统一 API”>“单视图应用程序”模板。

    Xamarin Studio - 选择应用程序类型

  2. 添加对 Azure 消息传送组件的引用。在“解决方案”视图中,右键单击你项目的“Components”文件夹,然后选择“获取更多组件”。搜索“Azure 消息传送”组件,并向你的项目添加该组件。

  3. AppDelegate.cs 中,添加以下 using 语句:

    using WindowsAzure.Messaging;
    
  4. 声明 SBNotificationHub 的实例:

    private SBNotificationHub Hub { get; set; }
    
  5. 使用以下变量创建 Constants.cs 类:

    // Azure app-specific connection string and hub path
    public const string ConnectionString = "<Azure connection string>";
    public const string NotificationHubPath = "<Azure hub path>";
    
  6. AppDelegate.cs 中,更新 FinishedLaunching() 以匹配以下内容:

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
            var pushSettings = UIUserNotificationSettings.GetSettingsForTypes (
                   UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
                   new NSSet ());
    
            UIApplication.SharedApplication.RegisterUserNotificationSettings (pushSettings);
            UIApplication.SharedApplication.RegisterForRemoteNotifications ();
        } else {
            UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes (notificationTypes);
        }
    
        return true;
    }
    
  7. 重写 AppDelegate.cs 中的 RegisteredForRemoteNotifications() 方法:

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        Hub = new SBNotificationHub(Constants.ConnectionString, Constants.NotificationHubPath);
    
        Hub.UnregisterAllAsync (deviceToken, (error) => {
            if (error != null)
            {
                Console.WriteLine("Error calling Unregister: {0}", error.ToString());
                return;
            }
    
            NSSet tags = null; // create tags if you want
            Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) => {
                if (errorCallback != null)
                    Console.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
            });
        });
    }
    
  8. 重写 AppDelegate.cs 中的 ReceivedRemoteNotification() 方法:

    public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
    {
        ProcessNotification(userInfo, false);
    }
    
  9. AppDelegate.cs 中创建以下 ProcessNotification() 方法:

    void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
    {
        // Check to see if the dictionary has the aps key.  This is the notification payload you would have sent
        if (null != options && options.ContainsKey(new NSString("aps")))
        {
            //Get the aps dictionary
            NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
    
            string alert = string.Empty;
    
            //Extract the alert text
            // NOTE: If you're using the simple alert by just specifying
            // "  aps:{alert:"alert msg here"}  ", this will work fine.
            // But if you're using a complex alert with Localization keys, etc.,
            // your "alert" object from the aps dictionary will be another NSDictionary.
            // Basically the JSON gets dumped right into a NSDictionary,
            // so keep that in mind.
            if (aps.ContainsKey(new NSString("alert")))
                alert = (aps [new NSString("alert")] as NSString).ToString();
    
            //If this came from the ReceivedRemoteNotification while the app was running,
            // we of course need to manually process things like the sound, badge, and alert.
            if (!fromFinishedLaunching)
            {
                //Manually show an alert
                if (!string.IsNullOrEmpty(alert))
                {
                    UIAlertView avAlert = new UIAlertView("Notification", alert, null, "OK", null);
                    avAlert.Show();
                }
            }
        }
    }
    

    Note

    你可以选择覆盖 FailedToRegisterForRemoteNotifications() 以处理无网络连接等情况。如果用户可能会在脱机模式下(例如飞行模式)下启动你的应用程序,并且你想要处理应用特定的推送消息方案,则此操作特别重要。

  10. 在你的设备上运行应用程序。

发送推送通知

Azure 门户中通过“通知中心”页面上“故障排除”工具集中的“测试发送”功能来发送通知,可以在应用中测试推送通知的接收情况,如以下屏幕中所示。

通常,推送通知通过后端服务(例如移动服务或者使用兼容库的 ASP.NET)进行发送。如果你的方案中没有可用的库,则你也可以使用 REST API 直接发送推送消息。

在本教程中,为了保持内容的简单性,我们只会演示如何在控制台应用程序(而不是后端服务)中,使用通知中心的 .NET SDK 发送通知,以此测试你的客户端应用。建议你接下来学习使用通知中心向用户推送通知教程,以了解如何从 ASP.NET 后端发送通知。不过,可以使用以下方法来发送通知:

(可选)通过 .NET 控制台应用发送推送通知

在本部分,你将使用简单的 .NET 控制台应用发送推送通知。为了演示本示例,我们将切换到已安装 Visual Studio 的 Windows 开发环境。

  1. 在 Visual Studio 中创建新的 Visual C# 控制台应用程序:

    Visual Studio - 新建控制台应用程序

  2. 在 Visual Studio 中,依次单击“工具”、“NuGet 包管理器”和“包管理器控制台”。

    包管理器控制台应显示在 Visual Studio 工作区的底部。

  3. 在“包管理器控制台”窗口中,将“默认项目”设置为新的控制台应用程序项目,然后在控制台窗口中执行以下命令:

    Install-Package Microsoft.Azure.NotificationHubs
    

    这将使用 Microsoft.Azure.Notification Hubs NuGet 包添加对 Azure 通知中心 SDK 的引用。

  4. 打开 Program.cs 文件,并添加以下 using 语句,确保我们可以使用 Azure 类和你主类中的函数:

    using Microsoft.Azure.NotificationHubs;
    
  5. 在你的 Program 类中,添加以下方法(不要忘了替换连接字符串中心名称):

    private static async void SendNotificationAsync()
    {
        NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>");
        var alert = "{"aps":{"alert":"Hello from .NET!"}}";
        await hub.SendAppleNativeNotificationAsync(alert);
    }
    
  6. Main 方法中添加以下行:

     SendNotificationAsync();
     Console.ReadLine();
    
  7. 按 F5 键以运行应用。数秒内,你应在设备上看到一条推送通知。无论你使用 Wi-Fi 或移动电话数据网络,确保设备上存在可用的 Internet 连接。

可以在 Apple 本地和推送通知编程指南中找到所有可能的负载。

(可选)从移动服务发送通知

在本部分,我们将使用移动服务通过节点脚本来发送推送通知。

若要使用移动服务发送通知,请按移动服务入门中的说明操作,然后:

  1. 登录到 Azure 经典门户并选择你的移动服务。

  2. 选择顶部的“计划程序”选项卡。

    Azure 经典门户 - 计划程序

  3. 创建新的计划作业,插入名称,然后选择“按需”。

    Azure 经典门户 - 新建作业

  4. 创建作业时,单击该作业名称。然后单击顶部栏上的“脚本”选项卡。

  5. 在你的计划程序函数中插入以下脚本。确保将占位符替换为你先前获取的通知中心名称和 DefaultFullSharedAccessSignature 的连接字符串。单击“保存”。

    var azure = require('azure');
    var notificationHubService = azure.createNotificationHubService('<Hubname>', '<SAS Full access >');
    notificationHubService.apns.send(
        null,
        {"aps":
            {
              "alert": "Hello from Mobile Services!"
            }
        },
        function (error)
        {
            if (!error) {
                console.warn("Notification successful");
            }
        }
    );
    
  6. 单击底部栏上的“运行一次”。你应在设备上收到警报。

后续步骤

在这个简单的示例中,你已将推送通知广播到所有 iOS 设备。若要针对特定客户,请参考教程使用通知中心将通知推送到用户。如果要按兴趣组划分用户,可以阅读使用通知中心发送突发新闻。请在通知中心指南适用于 iOS 的通知中心操作方法指南中了解有关如何使用通知中心的详细信息。