如何从平台通知服务检索 PNS 句柄?

How to retrieve a PNS Handle from the Platform Notification Service?

我有一个正在连接 Azure 后端服务的 Xamarin.iOS 应用程序,我希望我的服务向客户端应用程序发送通知。

Microsoft 文档解释了如何为不同的场景设置通知中心。我想我得到了其中的大部分,但是我不确定我是否理解 very first part,它用于从平台通知服务向 Retrieve PNS Handle 的 iOS 应用程序,如下所示图片:

看起来这是一些必须由客户端应用程序单独执行的任务,然后将其传达给后端服务以进行注册。

我感觉它发生在 this section 的第 10 步,当时 iOS 在方法 RegisteredForRemoteNotifications 上调用应用程序。在该回调中,应用程序被赋予 deviceToken:

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);

    Hub.UnregisterAllAsync (deviceToken, (error) => {
        if (error != null)
        {
            System.Diagnostics.Debug.WriteLine("Error calling Unregister: {0}", error.ToString());
            return;
        }

        NSSet tags = null; // create tags if you want
        Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) => {
            if (errorCallback != null)
                System.Diagnostics.Debug.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
        });
    });
}

问题

那是 deviceToken 我需要发送到后端服务以启动注册过程的 PNS 句柄吗?如果没有,我该如何联系 PNS 获取 Handle?

方法RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)是告诉delegate应用成功注册了Push Notification服务。

参数“deviceToken”是一个全球唯一的令牌,用于向推送通知服务标识此设备。

    NSSet tags = null; // create tags if you want

    Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) => 
    {
        if (errorCallback != null)
            System.Diagnostics.Debug.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
    });

因为您使用的是 Azure,Hub 已将令牌发送到上述方法中生成远程通知。所以如果你只想把一些东西推送给所有用户,你不需要做其他事情。如果你想推送给特定的用户,你可以注册一个标签作为参数。

该信息位于 documentation 中,但对于 C# 开发人员而言并不明显。

在 Objective-C 中,deviceToken 由 iOS 应用程序提供,正如@LucasZ 所提到的,在它注册到 PNS 之后。

但是我无法立即发送此 deviceToken,因为它不会被我服务中使用的 AppleRegistrationDescription class 接受。

我花了一些时间来熟悉 Objective-C 才发现这个令牌在发送到 Azure 之前实际上已经过转换:

NSSet* tagsSet = tags?tags:[[NSSet alloc] init];

NSString *deviceTokenString = [[token description]
        stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

    deviceTokenString = [[deviceTokenString stringByReplacingOccurrencesOfString:@" " withString:@""] uppercaseString];

我已经在 C# 中实现了类似的东西:

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    string pnsHandle = deviceToken.Description
                                  .Replace("<", string.Empty)
                                  .Replace(">", string.Empty)
                                  .Replace(" ", string.Empty)
                                  .ToUpper(); 

    Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);

    Hub.UnregisterAllAsync (pnsHandle, (error) => 
    {
        if (error != null)
        {
            System.Diagnostics.Debug.WriteLine("Error calling Unregister: {0}", error.ToString());
            return;
        }

        // In my use case, the tags are assigned by the server based on privileges.
        NSSet tags = null;

        Hub.RegisterNativeAsync(pnsHandle, tags, (errorCallback) => 
        {
            if (errorCallback != null)
                System.Diagnostics.Debug.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
        });
    });
}

回答我的问题,是的,deviceToken 是 PNS 句柄,但必须对其进行格式化。