通过Xamarin中的Azure模板推送通知(译文)
By S.F.
本文链接 https://www.kyfws.com/news/push-notifications-via-azure-templates-in-xamarin/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 12 分钟阅读 - 5863 个词 阅读量 0通过Xamarin中的Azure模板推送通知(译文)
原文地址:https://www.codeproject.com/Articles/5280120/Push-Notifications-via-Azure-Templates-in-Xamarin
原文作者:Arcadenut
译文由本站翻译
前言
如何在Xamarin中通过Azure模板实现推送通知 这提供了使用C#和Xamarin通过Azure实现推式通知所需的大多数信息.
我的Rant
当您只需要示例中简单明了的东西时,什么都不是让我烦恼的,要么是文档过于模糊,要么是极其复杂. 如果通过Azure将消息推送到移动设备,则两者都是. 我需要做的是为我正在为客户编写的应用程序支持推送通知.他们的员工可能正在使用Android或iOS设备.我的应用程序是使用Xamarin的C#. 我遇到的所有示例都没有包含我需要的所有信息,或者它们提供了过多的信息,无法掩盖所有重要的细节. 我的一大烦恼是基本没有价值的帮助文档. 如果您查看NotificationHubClient.GetRegistrationsByChannelAsync的帮助([https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient.getregistrationsbychannelasync?view=azure-dotnet](https ://docs.microsoft.com/zh-cn/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient.getregistrationsbychannelasync?view =azure-dotnet)),您会看到它可以在构造函数中使用几个参数.我需要的版本是
GetRegistrationsByChannelAsync (string pnsHandle, int top);
我知道的第一个参数是Azure提供给我的句柄.没问题,容易理解.我必须假设的下一个参数TOP意味着向我返回TOP N个注册,但是,该参数的说明是这样的:
Top Int32
The location of the registration.
好吧,现在我在想WTF是什么意思?注册的位置?他们是说我要所有注册都从TOP开始还是我要此PSN的第一个TOP注册? 漫不经心^时间到了.
开始之前
有两个假设. 第一个是您已经访问了特定于平台的站点和Azure,以将其设置为"推送通知".本文档是关于在客户端(当前为Android)和服务器端(无论您要执行此操作的地方,服务,应用程序等)执行推送通知代码的. 要设置集线器侧,请参见此处: https://console.firebase.google.com/ 和 [https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.NotificationHubs%2Fnamespaces%2FnotificationHubs](https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft. NotificationHubs%2Fnamespaces%2FnotificationHubs) 其次,您要使用模板,以便可以使用C#通过Azure执行设备不可知的推送,并且客户端使用Xamarin. 如果您使用的是C#和Xamarin以外的其他工具,那么其中一些可能仍然对您有用.
让我们开始吧
推送通知分为三个主要部分.
Azure(和特定于平台的站点)
在继续之前,应该已经设置好了.这是您的服务器与平台特定的推送服务(即Firebase)和设备之间的中介. 在Visual Studio(我使用的是2019 Enterprise)中,有一个适用于Azure的服务器资源管理器,您应确保已安装该服务器,因为它非常方便进行故障排除和测试,以确保所有配置均正确.如果您没有收到来自应用程序的通知,并且可以通过Azure资源管理器发送测试消息,则很有可能您的应用程序有故障. 设备正确注册后(将在"客户端"部分的文档下方进行进一步注册),该设备应显示在"设备注册"标签上,如下所示:
在这种情况下,该平台为Google(GCM),因为我使用的是Android设备进行测试.类型为"模板",因为我使用模板方法注册.您之所以要这样做,是因为这意味着在发送消息时,它将与设备/平台无关.如果"类型"显示为"本机",则意味着您必须发送专门针对该平台类型的消息,并使用专门针对该平台格式化的消息. 标签专用于设备,并在发送通知时用作过滤机制.任何具有特定TAG(每个值都用逗号分隔)的注册设备都将收到该通知.我在标签中放入的内容是用户的唯一ID,它们可能属于的组(管理,技术等…).据我了解,标签最多只能包含10个,但是我只需要几个标签就可以了,因此我尚未进行验证.
服务器端
服务器端实际上是微不足道的.每当我第一次尝试找出答案时,我通常都会创建一个简单的测试应用程序,并在其中编写代码以证明其有效,并确保我涵盖了所有基础知识.完成此操作后,我将创建一个可重用的类,以可在几乎任何地方使用的方式实现它. 乱跑时间… 在我看到的所有示例中,它们往往使问题变得过于复杂.他们使用多个类,单例模式等…这确实会使多余的杂物陷入困境.只是给我看一个简单的例子,我可以将其重构为自己的模式.更糟糕的是,在Azure推送通知示例的情况下,我看到它们是"这是基于先前的示例^",然后您再去看看,它也基于先前的示例,请冲洗并重复!啊. 无论如何….基本上,这是服务器端发送推送通知所需的全部操作. 您要做的第一件事是在从中发送通知的项目中安装名为" Microsoft.Azure.NotificationHubs"的NuGet软件包. 请参阅此处:https://azure.microsoft.com/en-us/services/notification-hubs/ 然后我们只需要以下代码:
public async void SendPushNotification(string p_title, string p_message, int p_assignmentID, string p_tags)
{
Dictionary<string, string> notificationParameters = new Dictionary<string, string>();
Microsoft.Azure.NotificationHubs.NotificationHubClient hub = null;
hub = Microsoft.Azure.NotificationHubs.NotificationHubClient.CreateClientFromConnectionString("<DefaultFullSharedAccessSignature>", "<hub name>");
notificationParameters.Add("Title", p_title);
notificationParameters.Add("Message", p_message);
notificationParameters.Add("AssignmentID", p_assignmentID.ToString());
await hub.SendTemplateNotificationAsync(notificationParameters, p_tags);
}
现在对发生的事情进行一些解释… 该行:
Microsoft.Azure.NotificationHubs.NotificationHubClient.CreateClientFromConnectionString
创建一个NotificationHubClient类的实例,该实例用于发送实际的通知. 第一个参数是" DefaultFullSharedAccessSignature",可以在Azure通知中心项目页的"访问策略"下找到.
第二个参数是通知中心的名称.如果您位于通知中心的" Azure页面"上,它将位于顶部,并且为/.您只需要集线器名称部分. 我不知道他们为什么要拥有命名空间,因为我从来不需要它.它可能用于更高级的方案.
字典" notificationParameters"只是要传递给Azure的参数的字典,因此它可以使用注册的模板填充传递的值来创建消息. 注意:参数名称区分大小写,因此请确保它们与您在事物的客户端中注册的名称匹配. 您可以传入任意数量的参数,但通常只传入3.我只需要标题,通知的正文以及应用程序执行某项操作(例如显示特定的Assignment或其他操作)可能需要的任何数据. 要实际发送通知,您需要调用方法
await hub.SendTemplateNotificationAsync(notificationParameters, p_tags);
第一个参数是我们的参数集合.第二个参数是代表"标签表达式"的字符串.目前,我只需要一次发送一个标签.但是,阅读文档和示例后,表达式似乎是简单的布尔逻辑. 类似于: || <标签B> 或<标签A> && <标签B> 有关更多信息,请参见此处: [https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient.sendtemplatenotificationasync?view=azure-dotnet#:~:text=String%2CString%3E)-,SendTemplateNotificationAsync( IDictionary%2C%20IEnumerable%3CString,(%22%7C%7C%22)](https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.azure.notificationhubs.notificationhubclient.sendtemplatenotificationasync?view=azure-dotnet#:〜:text =String%2CString%3E)-,SendTemplateNotificationAsync(IDictionary%2C%20IEnumerable%3CString,(%22%7C%7C%22)). 而已.很简单,很简单.
客户端
这是大部分工作要做的地方.我正在使用Xamarin表单,因此适用于此,但是,如果您以其他方式使用Xamarin,这可能对您仍然有用. 这个示例是以Android为中心的,因此您必须解决iOS方面的问题,因为我目前还没有这样做.尽管应遵循相同的原则,但我怀疑它不会增加太多代码. 客户端需要做一些事情. 我们将从定义接口开始.
using System;
using System.Collections.Generic;
using System.Text;
namespace MyApp.MultiPlatformInterfaces
{
public interface IRegisterNotifications
{
void RegisterDevice(string p_psnHandle, List<string> p_tags);
void UnRegisterDevice();
}
}
在此界面中,我将有两种方法要在"设备特定"项目中实现. " RegisterDevice"是最重要的一个.第一个参数是Azure将提供给客户端应用程序的PSN句柄.第二个参数是要向其注册该设备的标签列表. 标签是特定于设备的,因此您可以使用不同的标签注册不同的设备,也可以注册具有相同标签的所有设备.就我而言,我想在所有用户的所有设备上向相同的用户注册相同的标签,因此当我向该用户发送推送通知时,他们当前使用的设备无关紧要. 现在我们需要在设备特定项目(在本例中为Android)中实现该接口.
using MyApp.MultiPlatformInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
[assembly: Xamarin.Forms.Dependency(typeof(MyApp.Droid.RegisterNotifications))]
namespace MyApp.Droid
{
public class RegisterNotifications : MultiPlatformInterfaces.IRegisterNotifications
{
public void RegisterDevice(string p_psnHandle, List<string> p_tags)
{
AndroidFireBaseMessagingService.SendRegistrationToServer(p_psnHandle, p_tags);
}
void IRegisterNotifications.UnRegisterDevice()
{
AndroidFireBaseMessagingService.UnRegisterDevice();
}
}
}
此类使用依赖注入来完成此任务.
[assembly: Xamarin.Forms.Dependency(typeof(MyApp.Droid.RegisterNotifications))]
这就是Xamarin Forms处理需要从Xamarin Forms项目调用的平台特定代码的方式. 此类基本上是包装器,它包装用于在Azure中进行设备注册的真实代码. 下一节课有点复杂,但是大部分工作都在这里完成.这需要做一些解释,所以这就是全部,然后我将其分解. 注意:此代码是新代码,可能会做得更好一些,但是它可以正常工作,并且应说明需要完成的工作.
using System;
using Android.Util;
using Android.Support.V4.App;
using Android.App;
using System.Collections.Generic;
using Android.Content;
using System.Linq;
using System.Diagnostics;
using System.Threading.Tasks;
namespace MyApp.Droid
{
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class AndroidFireBaseMessagingService : Firebase.Messaging.FirebaseMessagingService
{
public override void OnNewToken(string token)
{
UtilityFunctions.SetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TOKEN, token);
UtilityFunctions.DeleteStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TAGS);
}
public override void OnMessageReceived(Firebase.Messaging.RemoteMessage message)
{
if (message.GetNotification() != null)
{
SendNotification(message.GetNotification().Body);
}
else
{
SendNotification(message.Data.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
}
}
private void SendNotification(string p_message)
{
SendNotification(new Dictionary<string, string> { { "Message", p_message } });
}
private async void SendNotification(Dictionary<string, string> p_values)
{
try
{
await Task.Run(() =>
{
Intent intent = null;
PendingIntent pendingIntent = null;
intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
if (p_values.ContainsKey("AssignmentID"))
{
intent.PutExtra("AssignmentID", p_values["AssignmentID"]);
}
pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID);
notificationBuilder.SetContentTitle("Message Title");
notificationBuilder.SetSmallIcon(Resource.Drawable.ic_launcher);
if (p_values.ContainsKey("Title"))
{
notificationBuilder.SetContentTitle(p_values["Title"]);
}
if (p_values.ContainsKey("Message"))
{
notificationBuilder.SetContentText(p_values["Message"]);
}
notificationBuilder.SetAutoCancel(true);
notificationBuilder.SetShowWhen(false);
notificationBuilder.SetContentIntent(pendingIntent);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
});
}
catch (Exception ex)
{
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION, ex.ToString());
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION_DATE, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff"));
}
}
public static async Task<string> GetRegistrationIdAsync(string p_handle, Microsoft.Azure.NotificationHubs.NotificationHubClient p_hub)
{
Microsoft.Azure.NotificationHubs.CollectionQueryResult<Microsoft.Azure.NotificationHubs.RegistrationDescription> registrations = null;
string psnHandle = "";
string newRegistrationId = null;
if (string.IsNullOrEmpty(p_handle))
{
throw new ArgumentNullException("handle could not be empty or null");
}
psnHandle = p_handle.ToUpper();
registrations = await p_hub.GetRegistrationsByChannelAsync(psnHandle, 100);
foreach (Microsoft.Azure.NotificationHubs.RegistrationDescription registration in registrations)
{
if (newRegistrationId == null)
{
newRegistrationId = registration.RegistrationId;
}
else
{
await p_hub.DeleteRegistrationAsync(registration);
}
}
if (newRegistrationId == null)
{
newRegistrationId = await p_hub.CreateRegistrationIdAsync();
}
return newRegistrationId;
}
public static async void SendRegistrationToServer(string p_token, List<string> p_tags)
{
Microsoft.Azure.NotificationHubs.NotificationHubClient hub;
Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription registration;
Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription registrationResult;
string messageTemplate = "";
string tags = "";
foreach (var item in p_tags)
{
if (tags != "")
{
tags += ",";
}
tags += item;
}
hub = Microsoft.Azure.NotificationHubs.NotificationHubClient.CreateClientFromConnectionString(UtilityFunctions.AZURE_FULL_ENDPOINT, UtilityFunctions.AZURE_NOTIFICATION_HUB_NAME);
messageTemplate = "{\"data\":{\"Title\":\"$(title)\",\"Message\":\"$(message)\", \"AssignmentID\":\"$(assignmentID)\"}}";
registration = new Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription(p_token, messageTemplate);
try
{
registration.RegistrationId = await GetRegistrationIdAsync(p_token, hub);
registration.Tags = new HashSet<string>(p_tags);
registrationResult = await hub.CreateOrUpdateRegistrationAsync(registration);
UtilityFunctions.SetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TAGS, tags);
UtilityFunctions.SetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_REGID, registration.PnsHandle);
}
catch (Exception ex)
{
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION, ex.ToString());
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION_DATE, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff"));
}
}
public static async void UnRegisterDevice()
{
//TODO: Implment later
}
}
}
此类定义为服务,并且处理来自Android的2个意图.
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class AndroidFireBaseMessagingService : Firebase.Messaging.FirebaseMessagingService
首次运行您的应用程序时,它将调用此方法:
public override void OnNewToken(string token)
{
UtilityFunctions.SetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TOKEN, token);
UtilityFunctions.DeleteStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TAGS);
}
调用此方法,并从Firebase传递令牌.我只是保存此令牌以备后用(我有一个Utility类,可以处理诸如加载和保存值之类的事情,这就是UtilityFunction.SetStoredValue的用途).您可以将值存储在所需的任何位置,也可以从此处直接调用Register方法. 我保存它是因为我需要首先允许用户在Android应用中对自己进行身份验证,这样我才能知道他们是谁.他们通过身份验证后,稍后将需要此令牌. 只要您的应用程序收到推送通知,就会调用以下代码.
public override void OnMessageReceived(Firebase.Messaging.RemoteMessage message)
{
if (message.GetNotification() != null)
{
SendNotification(message.GetNotification().Body);
}
else
{
SendNotification(message.Data.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
}
}
此行的原因:
SendNotification(message.Data.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
因为message.Data
是一个IDictionary,我更喜欢使用Dictionary,所以我使用了一些Lambda来将其从一个转换为另一个.
我有两种方法可以处理此问题.第一个只是重载的方法,该方法调用执行实际工作的main方法.
private void SendNotification(string p_message)
{
SendNotification(new Dictionary<string, string> { { "Message", p_message } });
}
这是完成实际工作的第二个.与任何移动设备一样,您需要对用户友好,并且不要锁定您的UI,因此我们在Task中运行它. p_values是服务器发送过来的参数的集合.我不会在这部分进行详细介绍,而是说这是打开应用程序(MainActivity)并显示实际通知的部分.
private async void SendNotification(Dictionary<string, string> p_values)
{
try
{
await Task.Run(() =>
{
Intent intent = null;
PendingIntent pendingIntent = null;
intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
if (p_values.ContainsKey("AssignmentID"))
{
intent.PutExtra("AssignmentID", p_values["AssignmentID"]);
}
pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID);
notificationBuilder.SetContentTitle("Message Title");
notificationBuilder.SetSmallIcon(Resource.Drawable.ic_launcher);
if (p_values.ContainsKey("Title"))
{
notificationBuilder.SetContentTitle(p_values["Title"]);
}
if (p_values.ContainsKey("Message"))
{
notificationBuilder.SetContentText(p_values["Message"]);
}
notificationBuilder.SetAutoCancel(true);
notificationBuilder.SetShowWhen(false);
notificationBuilder.SetContentIntent(pendingIntent);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
});
}
catch (Exception ex)
{
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION, ex.ToString());
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION_DATE, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff"));
}
}
现在,稍后在我的应用程序中(在用户进行身份验证之后)将调用的实际方法是:
public static async void SendRegistrationToServer(string p_token, List<string> p_tags)
{
Microsoft.Azure.NotificationHubs.NotificationHubClient hub;
Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription registration;
Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription registrationResult;
string messageTemplate = "";
string tags = "";
foreach (var item in p_tags)
{
if (tags != "")
{
tags += ",";
}
tags += item;
}
hub = Microsoft.Azure.NotificationHubs.NotificationHubClient.CreateClientFromConnectionString(UtilityFunctions.AZURE_FULL_ENDPOINT, UtilityFunctions.AZURE_NOTIFICATION_HUB_NAME);
messageTemplate = "{\"data\":{\"Title\":\"$(title)\",\"Message\":\"$(message)\", \"AssignmentID\":\"$(assignmentID)\"}}";
registration = new Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription(p_token, messageTemplate);
try
{
registration.RegistrationId = await GetRegistrationIdAsync(p_token, hub);
registration.Tags = new HashSet<string>(p_tags);
registrationResult = await hub.CreateOrUpdateRegistrationAsync(registration);
UtilityFunctions.SetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TAGS, tags);
UtilityFunctions.SetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_REGID, registration.PnsHandle);
}
catch (Exception ex)
{
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION, ex.ToString());
UtilityFunctions.SetStoredValue(UtilityFunctions.LAST_EXCEPTION_DATE, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff"));
}
}
代码的导入位是这个.这定义了特定于平台的消息.对于其他设备类型,您将使用" FcmTemplateRegistrationDescription"之外的其他类,并且您的消息模板看起来将是特定于平台的.
messageTemplate = "{\"data\":{\"Title\":\"$(title)\",\"Message\":\"$(message)\", \"AssignmentID\":\"$(assignmentID)\"}}";
registration = new Microsoft.Azure.NotificationHubs.FcmTemplateRegistrationDescription(p_token, messageTemplate);
对于Android,这是一条Json消息.这是/的字典.令牌只能是$().如果您输入"这是我的代币$(blah)“之类的内容,那么"这是我的代币$(blah)“将是显示在设备上的内容,而不是您可能期望的内容. 您可以在模板中添加所需的任何内容,只要它遵循该格式即可.这些键区分大小写,因此请记住这一点. 这条线很重要!:
registration.RegistrationId = await GetRegistrationIdAsync(p_token, hub);
这将调用此方法:
public static async Task<string> GetRegistrationIdAsync(string p_handle, Microsoft.Azure.NotificationHubs.NotificationHubClient p_hub)
{
Microsoft.Azure.NotificationHubs.CollectionQueryResult<Microsoft.Azure.NotificationHubs.RegistrationDescription> registrations = null;
string psnHandle = "";
string newRegistrationId = null;
if (string.IsNullOrEmpty(p_handle))
{
throw new ArgumentNullException("handle could not be empty or null");
}
psnHandle = p_handle.ToUpper();
registrations = await p_hub.GetRegistrationsByChannelAsync(psnHandle, 100);
foreach (Microsoft.Azure.NotificationHubs.RegistrationDescription registration in registrations)
{
if (newRegistrationId == null)
{
newRegistrationId = registration.RegistrationId;
}
else
{
await p_hub.DeleteRegistrationAsync(registration);
}
}
if (newRegistrationId == null)
{
newRegistrationId = await p_hub.CreateRegistrationIdAsync();
}
return newRegistrationId;
}
此方法将在Azure上为该PSN句柄查找一个注册ID,如果存在,则将其删除,然后重新创建.如果您多次注册设备,则您的应用程序可能会收到重复的推送通知. 该方法基于Premchandra Singh的帖子: https://stackoverflow.com/questions/31912711/azure-notification-hub-tags-not-creating-nor-updating-to-target-specific-user 然后,我们设置标签并调用将实际在Azure中注册设备的方法.
registration.Tags = new HashSet<string>(p_tags);
registrationResult = await hub.CreateOrUpdateRegistrationAsync(registration);
在我的代码中,我没有对” registrationResult"进行任何操作,但是可以根据需要保留这些信息.
一旦完成,我将保存PnsHandle供以后使用.
这里缺少的部分是实际调用SendRegistrationToServer
的代码.用户进行身份验证后,这会在我的Xamarin表单页面中发生.我这样做的原因是我需要知道他们是谁,以便可以在设备上为该用户设置特定标签.
我有一个叫的方法:
public static void RegisterDeviceForPushNotifications()
{
MultiPlatformInterfaces.IRegisterNotifications reg = null;
List<string> tagList = new List<string>();
string token = "";
string tags = "";
tags = UtilityFunctions.GetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TAGS, "");
if (tags == "")
{
token = UtilityFunctions.GetStoredValue(UtilityFunctions.AZURE_NOTIFICATIONS_REGISTRATION_TOKEN, "");
tagList.Add(App.LoggedInDcw.DirectCareWorkerID.ToString());
tagList.Add("DCW");
reg = Xamarin.Forms.DependencyService.Get<MultiPlatformInterfaces.IRegisterNotifications>();
reg.RegisterDevice(token, tagList);
}
}
这将调用平台特定版本的注册代码,该代码将进行实际注册. 就是这样.希望我能介绍足够多的内容,以帮助您使推送通知正常工作.
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# Azure Xamarin 新闻 翻译