向 Xamarin.iOS 应用添加推送通知

概述

本教程介绍如何向 Xamarin.iOS 快速入门项目添加推送通知,以便每次插入一条记录时,向设备发送一条推送通知。

如果不使用下载的快速入门服务器项目,则需要推送通知扩展包。有关详细信息,请参阅使用适用于 Azure 移动应用的 .NET 后端服务器 SDK

先决条件

在 Apple 的开发人员门户上为推送通知注册应用

配置移动应用以发送推送通知

  1. 在 Mac 上启动“Keychain Access”。在左侧导航栏的“类别”下打开“我的证书”。找到在上一节中下载的 SSL 证书,并公开其内容。仅选择证书(不选择私钥),并将其导出
  2. Azure 门户中,单击“浏览全部”>“应用服务”,然后单击移动应用后端。在“设置”下,单击“应用服务推送”,然后单击通知中心名称。转到“Apple 推送通知服务”>“上传证书”。上传 .p12 文件,选择正确的模式(具体取决于之前的客户端 SSL 证书是生产还是沙盒)。保存所有更改。

现在,服务已配置为在 iOS 上使用通知中心。

更新服务器项目以发送推送通知

在本部分中,更新现有移动应用后端项目中的代码,以便在每次添加新项目时推送通知。此功能由 Azure 通知中心的模板功能提供支持,并且启用了跨平台推送。使用模板为推送通知注册了各种客户端,单个通用推送可到达所有客户端平台。

选择以下与你的后端项目类型(.NET 后端Node.js 后端)匹配的一个过程。

.NET 后端项目

  1. 在 Visual Studio 中,右键单击服务器项目并单击“管理 NuGet 包”。搜索 Microsoft.Azure.NotificationHubs,然后单击“安装”。这将安装通知中心库,以便从后端发送通知。
  2. 在服务器项目中,打开“控制器”>“TodoItemController.cs”,使用以下语句进行添加:

    using System.Collections.Generic;
    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.Mobile.Server.Config;
    
  3. PostTodoItem 方法中,在调用 InsertAsync 后添加如下代码:

    // Get the settings for the server project.
    HttpConfiguration config = this.Configuration;
    MobileAppSettingsDictionary settings = 
        this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
    
    // Get the Notification Hubs credentials for the Mobile App.
    string notificationHubName = settings.NotificationHubName;
    string notificationHubConnection = settings
        .Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
    
    // Create a new Notification Hub client.
    NotificationHubClient hub = NotificationHubClient
    .CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
    
    // Sending the message so that all template registrations that contain "messageParam"
    // will receive the notifications. This includes APNS, GCM, WNS, and MPNS template registrations.
    Dictionary<string,string> templateParams = new Dictionary<string,string>();
    templateParams["messageParam"] = item.Text + " was added to the list.";
    
    try
    {
        // Send the push notification and log the results.
        var result = await hub.SendTemplateNotificationAsync(templateParams);
    
        // Write the success result to the logs.
        config.Services.GetTraceWriter().Info(result.State.ToString());
    }
    catch (System.Exception ex)
    {
        // Write the failure result to the logs.
        config.Services.GetTraceWriter()
            .Error(ex.Message, null, "Push.SendAsync Error");
    }
    

    插入新项时,会发送包含 item.text 的模板通知。

  4. 重新发布服务器项目。

Node.js 后端项目

  1. 如果尚未执行此操作,请下载快速入门后端项目或使用 Azure 门户中的在线编辑器

  2. 将 todoitem.js 文件中的现有代码替换为以下内容:

    var azureMobileApps = require('azure-mobile-apps'),
    promises = require('azure-mobile-apps/src/utilities/promises'),
    logger = require('azure-mobile-apps/src/logger');
    
    var table = azureMobileApps.table();
    
    table.insert(function (context) {
    // For more information about the Notification Hubs JavaScript SDK, 
    // see http://aka.ms/nodejshubs
    logger.info('Running TodoItem.insert');
    
    // Define the template payload.
    var payload = '{"messageParam": "' + context.item.text + '" }';  
    
    // Execute the insert.  The insert returns the results as a Promise,
    // Do the push as a post-execute action within the promise flow.
    return context.execute()
        .then(function (results) {
            // Only do the push if configured
            if (context.push) {
                // Send a template notification.
                context.push.send(null, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });
            }
            // Don't forget to return the results from the context.execute()
            return results;
        })
        .catch(function (error) {
            logger.error('Error while running context.execute: ', error);
        });
    });
    
    module.exports = table;  
    

    插入新项时,会发送包含 item.text 的模板通知。

  3. 编辑本地计算机上的文件时,请重新发布服务器项目。

配置 Xamarin.iOS 项目

在 Xamarin Studio 中配置 iOS 项目

  1. 在 Xamarin.Studio 中,打开 Info.plist,然后使用前面随新应用 ID 创建的捆绑 ID 更新“捆绑标识符”。

  2. 向下滚动到后台模式。选中“启用后台模式”框和“远程通知”框。

  3. 在解决方案面板中双击项目以打开“项目选项”。

  4. 在“生成”下面选择“iOS 捆绑签名”,并选择刚刚为此项目设置的相应标识和预配配置文件。

    这确保项目使用新配置文件进行代码签名。有关正式的 Xamarin 设备设置文档,请参阅 Xamarin 设备设置

在 Visual Studio 中配置 iOS 项目

  1. 在 Visual Studio 中,右键单击项目,然后单击“属性”。
  2. 在属性页中,单击“iOS 应用程序”选项卡,然后使用先前创建的 ID 更新“标识符”。

  3. 在“iOS 捆绑签名”选项卡中,选择刚为此项目设置的相应的标识符和预配配置文件。

    这确保项目使用新配置文件进行代码签名。有关正式的 Xamarin 设备设置文档,请参阅 Xamarin 设备设置

  4. 双击 Info.plist 打开它,然后在“后台模式”下面启用“远程通知”。

向应用程序添加推送通知

  1. QSTodoService 中,添加以下属性使 AppDelegate 可以获取移动客户端:

        public MobileServiceClient GetClient {
        get
        {
            return client;
        }
        private set
        {
            client = value;
        }
    }
    
  2. AppDelegate.cs 文件顶部添加以下 using 语句。

    using Microsoft.WindowsAzure.MobileServices;
    using Newtonsoft.Json.Linq;
    
  3. AppDelegate 中,重写 FinishedLaunching 事件:

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        // registers for push for iOS8
        var settings = UIUserNotificationSettings.GetSettingsForTypes(
            UIUserNotificationType.Alert
            | UIUserNotificationType.Badge
            | UIUserNotificationType.Sound,
            new NSSet());
    
        UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
        UIApplication.SharedApplication.RegisterForRemoteNotifications();
    
        return true;
    }
    
  4. 在同一文件中,重写 RegisteredForRemoteNotifications 事件。在此代码中,将注册一个简单的模板通知,服务器会将此通知发送到所有支持的平台。

    有关使用通知中心的模板的详细信息,请参阅模板

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        MobileServiceClient client = QSTodoService.DefaultService.GetClient;
    
        const string templateBodyAPNS = "{"aps":{"alert":"$(messageParam)"}}";
    
        JObject templates = new JObject();
        templates["genericMessage"] = new JObject
        {
            {"body", templateBodyAPNS}
        };
    
        // Register for push with your mobile app
        var push = client.GetPush();
        push.RegisterAsync(deviceToken, templates);
    }
    
  5. 然后,重写 DidReceivedRemoteNotification 事件:

    public override void DidReceiveRemoteNotification (UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
    {
        NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
    
        string alert = string.Empty;
        if (aps.ContainsKey(new NSString("alert")))
            alert = (aps [new NSString("alert")] as NSString).ToString();
    
        //show alert
        if (!string.IsNullOrEmpty(alert))
        {
            UIAlertView avAlert = new UIAlertView("Notification", alert, null, "OK", null);
            avAlert.Show();
        }
    }
    

你的应用现已更新,可支持推送通知。

在应用程序中测试推送通知

  1. 在支持 iOS 的设备中按“运行”按钮生成项目并启动应用,然后单击“确定”接受推送通知。

    Note

    你必须显式接受来自应用程序的推送通知。此请求只会在首次运行应用程序时出现。

  2. 在应用中,键入一项任务,然后单击加号 (+) 图标。

  3. 检查是否已收到通知,然后单击“确定”以取消通知。

  4. 重复步骤 2 并立即关闭应用,然后检查是否已显示通知。

你已成功完成本教程。