3
votes

I need some help with registering an iOS device for multiple templates with Azure Notification Hubs.

Registering for a single template works fine but it seems like when registering for multiple templates from a single device, the second template that is registered for always works fine and the first template that is registered for does not work correctly.

I found something the other day saying that each template had to have a unique PNS Handle but even getting (what I think might be) 2 unique PNS Handles does not seem to work.

Templates #1:

{"aps":{"title":"$(emergencyTitle)","alert":"$(emergencyMessage)","tags":"$(emergencyTags)"}}

Template #2:

{"aps":{"content-available":1,"title":"$(regularTitle)","alert":"$(regularMessage)","inAppMessage":"$(regularMessage)","tags":"$(regularTags)"}}

The code below gets called twice (which I was hoping would get 2 unique PNS Handles). Each time, it saves the deviceToken in a variable so that I can register the 2 templates with them:

if(UIDevice.CurrentDevice.CheckSystemVersion(8, 0)) {
    UIApplication.SharedApplication.RegisterUserNotificationSettings(UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new Foundation.NSSet()));

    UIApplication.SharedApplication.RegisterForRemoteNotifications();
} else {
    UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound);
}

Then the following stripped down code makes the call to the notification hubs to try and register the 2 templates:

Hub = Hub ?? new WindowsAzure.Messaging.SBNotificationHub(Constants.ConnectionString, Constants.NotificationHubPath);

// App.PushNotificationPnsHandles is a Dictionary<string, object> that holds an 'emergency' or 'regular' key and the deviceTokens
// Constants.EmergencyNotificationTemplate and Constants.RegularNotificationTemplate hold the template strings

Hub.UnregisterAllAsync((NSData)App.PushNotificationPnsHandles["emergency"], error => {
    Hub.RegisterTemplateAsync((NSData)App.PushNotificationPnsHandles["emergency"], "EmergencyTemplate", Constants.EmergencyNotificationTemplate, System.DateTime.Now.AddDays(90).ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US")), new NSSet(), errorCallback => { });
});

Hub.UnregisterAllAsync((NSData)App.PushNotificationPnsHandles["regular"], error => {
    Hub.RegisterTemplateAsync((NSData)App.PushNotificationPnsHandles["regular"], "RegularTemplate", Constants.RegularNotificationTemplate, System.DateTime.Now.AddDays(90).ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US")), new NSSet(), errorCallback => { });
});

Again, if I make a single call to register for the emergency template everything works great. If I make a single call to register for the regular template everything works great.

If I try to register for the emergency template first and then the regular template, then I send an emergency push notification, a push notification does indeed arrive at the phone but it contains no text in any of the variables... Not sure what I am doing wrong here. Thanks.

Edit: Looking in the Notification Hub debug window in Visual Studio, I can see 2 registrations, each with a different Registration ID but with the same PNS Identifier. If this is the case then I am not sure how to get unique identifiers for each template.

1

1 Answers

6
votes
  1. A specific app on a specific device is identified by one particular PNS handle. You can't have multiple different PNS handles for the same app on the same device.
  2. Don't use UnregisterAllAsync() if you don't want to actually delete all registrations. Just use RegisterTemplateAsync(), it will create or update a template registration.
  3. If you want to use multiple templates, you have to distinguish the registrations with different tags, not with different PNS handles, since the PNS handle is always identical.

So, what you have to do is:

  1. Don't get the PNS handle twice, but only once, since it is always the same anyways.
  2. Remove the calls to UnregisterAllAsync(), RegisterTemplateAsync() is sufficient.
  3. Pass at least one tag to RegisterTemplateAsync() instead of an empty NSSet, and make sure the tag is different for each of your template registrations, e.g. "template:emergency" and "template:regular".
  4. If you want to send a "regular" notification, provide the "template:regular" tag to address the right registration, if you want to send an "emergeny" notification, use the "template:emergency" tag.