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

概述

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

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

先决条件

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

  • 为应用注册应用 ID。 创建显式应用 ID (而不是通配符应用 ID) 对于捆绑 ID,请使用 Xcode 快速入门项目中的确切捆绑 ID。 此外,必须选择“推送通知”选项。
  • 接下来,为了准备配置推送通知,请创建“开发”或“分发”SSL 证书。

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

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

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

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

在本部分中,更新现有移动应用后端项目中的代码,以便在每次添加新项目时发送推送通知。 此过程由 Azure 通知中心的模板功能提供支持,允许跨平台推送。 各种客户端使用模板注册推送通知,因此只需单个通用推送即可将内容发送到所有客户端平台。

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

.NET 后端项目

  1. 在 Visual Studio 中,右键单击服务器项目。 然后选择“管理 NuGet 包”。 搜索 Microsoft.Azure.NotificationHubs,并选择“安装” 。 此过程将安装通知中心库,以便从后端发送通知。

  2. 在服务器项目中,打开“控制器”>“TodoItemController.cs”。 然后,添加以下 using 语句:

    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);
    
    // Send the message so that all template registrations that contain "messageParam"
    // 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. 设置后端项目。

  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 https://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 的设备中按“运行”按钮,以生成项目并启动应用,然后单击“确定”接受推送通知。

    注意

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

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

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

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

已成功完成本教程。