This is all we do in our AppDelegate class.
public override async void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
bool ShouldComplete = true;
// Validate if we have already got a registration
try
{
string validation = NSUserDefaults.StandardUserDefaults.StringForKey("InitialTagRegistration");
if (validation.Contains("Completed"))
{
ShouldComplete = false;
}
}
catch (Exception genEx)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[EXCEPTION] - Exception has been hit! - Message: " + genEx.Message + " | Source: " + genEx);
}
Hub = new SBNotificationHub(ConfigurableSettings.NotificationHubConnectionString, ConfigurableSettings.NotificationHubPathName);
ApplicationState.SetValue("NotificationHub", Hub);
// Get previous device token
NSData oldDeviceToken = await ApplicationSettings.RetrieveDeviceToken();
// If the token has changed unregister the old token and save the new token to UserDefaults.
if (oldDeviceToken != null)
{
if (oldDeviceToken.ToString() != deviceToken.ToString())
{
try
{
Hub.UnregisterAllAsync(oldDeviceToken, (error) =>
{
//check for errors in unregistration process.
if (error != null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + error + " | Source: " + "Unregistering old device token against the notification hub.");
//exit out of the code here because we can't keep our hub clean without being able to remove the device from our registration list.
return;
}
else
{
ShouldComplete = true;
}
});
}
catch (Exception genEx)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + genEx.Message + " | Source: " + genEx + Environment.NewLine + Environment.NewLine);
}
}
}
else
{
// Store current device token
bool res = await ApplicationSettings.CacheDeviceToken(deviceToken);
}
// Check if we need to perform our initial registrations
if (ShouldComplete)
{
NSSet RegisteredTags = await ApplicationSettings.RetrieveUserTags();
if (RegisteredTags == null)
{
RegisteredTags = new NSSet("AppleDevice");
}
//Register the device against the notification hub keeping the details accurate at all times.
Hub.RegisterNativeAsync(deviceToken, RegisteredTags, (errorCallback) =>
{
if (errorCallback != null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + errorCallback + " | Source: " + "Registering device token against the notification hub.");
}
else
{
if (deviceToken != null)
{
NSUserDefaults.StandardUserDefaults.SetString("Completed", "InitialTagRegistration");
NSUserDefaults.StandardUserDefaults.Synchronize();
}
}
});
}
}
The long and short of it is that you don't need to do anything to the device token before passing it up to the azure notification hub. That's what solved the problem for us, ours has been running in an active application for months now without any issues. Hope this helps.
EDIT: in order to update the tags when a user logs in, we store the device token for use later on, and when the user logs in we use the following method in a seperate class to facilitate updating the tags:
public static async Task<bool> UpdateTags(StaffProfile user)
{
//Get the instance of the Notification hub
SBNotificationHub UpdateHub = new SBNotificationHub(ConfigurableSettings.NotificationHubConnectionString, ConfigurableSettings.NotificationHubPathName);
//Grab the current device token that was stored during the start up process.
NSData CurrentDeviceToken = await ApplicationSettings.RetrieveDeviceToken();
//Get and create the tags we want to use.
string EmailTag = string.Empty;
string StoreTag = string.Empty;
string OrganisationTag = "AppleDevice:OrgTag";
string GenericTag = "AppleDevice:StaffTag";
if (!string.IsNullOrWhiteSpace(user.Email))
{
EmailTag = user.Email;
//Remove unwanted spaces and symbols.
EmailTag = EmailTag.Replace(" ", "");
EmailTag = string.Format("AppleDevice:{0}", EmailTag);
}
if (!string.IsNullOrWhiteSpace(user.Store?.Name))
{
StoreTag = user.Store.Name;
//Remove unwanted space.
StoreTag = StoreTag.Replace(" ", "");
StoreTag = string.Format("AppleDevice:{0}", StoreTag);
}
//Create array of strings to the currently fixed size of 3 items.
NSString[] TagArray = new NSString[4];
//Only add in the tags that contain data.
if (!string.IsNullOrEmpty(EmailTag)) { TagArray[0] = (NSString)EmailTag; }
if (!string.IsNullOrEmpty(StoreTag)) { TagArray[1] = (NSString)StoreTag; }
if (!string.IsNullOrEmpty(OrganisationTag)) { TagArray[2] = (NSString)OrganisationTag; }
if (!string.IsNullOrEmpty(GenericTag)) { TagArray[3] = (NSString)GenericTag; }
NSSet tags = new NSSet(TagArray);
// Store our tags into settings
ApplicationSettings.CacheUserTags(tags);
try
{
if (CurrentDeviceToken == null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: Device token is empty." + Environment.NewLine + Environment.NewLine);
}
else
{
UpdateHub.RegisterNativeAsync(CurrentDeviceToken, tags, (error) =>
{
//check for errors in unregistration process.
if (error != null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + error + " | Source: " + "Registering against hub with new tags." + Environment.NewLine + Environment.NewLine);
// Lets do this so that we can force the initial registration to take place again.
NSUserDefaults.StandardUserDefaults.SetString("Failed", "InitialTagRegistration");
NSUserDefaults.StandardUserDefaults.Synchronize();
}
else
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[INFORMATION] - Message: Successful Registration - Source: Registering against hub with new tags." + Environment.NewLine + Environment.NewLine);
}
});
}
}
catch (Exception genEx)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + genEx.Message + " | Source: " + genEx + Environment.NewLine + Environment.NewLine);
}
return await Task.FromResult(true);
}