I have an Xamarin.iOS application that is connecting an Azure backend service and I want my service to send notifications to the client applications.
The Microsoft documentation explains how to set up the Notification Hub for different scenario. I think I am getting most of it, however I am not sure I understood the very first part, which is for the iOS application to Retrieve PNS Handle
from the Platform Notification Service, as shown in the following picture:
It looks like this is some task that must be performed by the client application alone and then communicate this to the backend service for the registration.
I have a feeling that it happens at the 10th step of this section, when iOS calls the application back on the method RegisteredForRemoteNotifications
. In that callback, the application is given a 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());
});
});
}
Question
Is that deviceToken
the PNS Handle that I need to send to the backend service to start the registration process? If not, how am I supposed to contact the PNS to get the Handle?
The information is in the documentation but not in an obvious form for a C# developer.
In Objective-C, the deviceToken
is provided by the iOS application, as mentioned by @LucasZ, after it got registered against the PNS.
However I can't just send this deviceToken
right away as it will not be accepted by the AppleRegistrationDescription
class used in my Service.
It took me a while to get more familiar with Objective-C to figure out that this token was actually transformed before being sent to Azure:
NSSet* tagsSet = tags?tags:[[NSSet alloc] init];
NSString *deviceTokenString = [[token description]
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
deviceTokenString = [[deviceTokenString stringByReplacingOccurrencesOfString:@" " withString:@""] uppercaseString];
I have implemented something similar in 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());
});
});
}
To answer my question, yes, the deviceToken
is the PNS Handle but it must be formatted.