I'm trying to set up push notifications via Azure NotificationHub (using these guides). Android went fine, but iOS...
No matter what I do, I do not receive any callbacks from RegisterNative / RegisterTemplate methods of SBNotificationHub, and no registrations appear in the hub.
My code (pretty straightforward):
public static void SubscribeToAzure(NSData deviceToken, string[] subscriptionTags = null, bool bUnsubscribe = false)
{
try
{
var Hub = new SBNotificationHub(AppConstants.ListenConnectionString, AppConstants.NotificationHubName);
Logger.WriteLine($"Unsubscribing from AzureHub [{deviceToken}]....");
Hub.UnregisterAll(deviceToken, (error) =>
{
if (error != null)
{
Logger.WriteLine($"SubscribeToAzure: Unable to call unregister, {error}");
return;
}
RuntimeInfo.AzureSubscribed = false;
if (bUnsubscribe)
return;
Logger.WriteLine($"Register native in AzureHub [{deviceToken}]....");
var tags = subscriptionTags != null ? new NSSet(subscriptionTags.ToArray()) : new NSSet("default");
Hub.RegisterNative(deviceToken, tags, errorCallback =>
{
// !!! never got here !!!
if (errorCallback != null)
Logger.WriteLine($"RegisterNative error: {errorCallback}");
else
Logger.WriteLine($"RegisterNative OK");
});
Logger.WriteLine("Register template in AzureHub....");
var templateExpiration = DateTime.Now.AddDays(120).ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));
Hub.RegisterTemplate(deviceToken, "defaultTemplate", AppConstants.APNTemplateBody, templateExpiration, tags, errorCallback =>
{
// !!! never got here !!!
if (errorCallback != null)
{
Logger.WriteLine($"RegisterTemplateAsync error: {errorCallback}");
}
else
{
Logger.WriteLine("Subscribed to Azure successfully.");
RuntimeInfo.AzureSubscribed = true;
}
});
Logger.WriteLine("Registrations passed....");
});
}
catch(Exception e)
{
Logger.WriteLine($"SubscribeToAzure: Whole deal failed, {e.Message}");
}
}
Always get this log messages (no callbacks called):
[22.10.2020 18:13:43]: Unsubscribing from AzureHub [{length = 32, bytes = 0x342c9bc5 d75ffb0b d68078d0 47e94320 ... e08989c9 66a13a37}]....
[22.10.2020 18:13:44]: Register native in AzureHub [{length = 32, bytes = 0x342c9bc5 d75ffb0b d68078d0 47e94320 ... e08989c9 66a13a37 }]....
[22.10.2020 18:13:44]: Register template in AzureHub....
[22.10.2020 18:13:44]: Registrations passed....
And no iOS registrations in the hub. And no errors anywhere.
I tried both certificate and token authentication modes, with no luck.
I have double-, triple- and quadruple-checked all certificates, statuses, keys, ids, etc.
Using iOS SDK 14.0, iPhone X iOS 14.0.1, Xamarin Forms 4.8.0.1560, Xamarin.Azure.NotificationHubs.iOS 3.1.0.
=======
I was advised to move from SBNotificationHub to MSNotificationHub.
Got exactly the same result: no response if something went wrong or not. And no registrations in the hub.
public static void SubscribeToAzure(NSData deviceToken, string[] subscriptionTags = null, bool bUnsubscribe = false)
{
RuntimeInfo.AzureSubscribed = false;
if (bUnsubscribe)
{
// ??
}
else
{
try
{
Logger.WriteLine("Subscribing to Azure Hub....");
MSNotificationHub.Start(AppConstants.ListenConnectionString, AppConstants.NotificationHubName);
MSNotificationHub.SetDelegate(new NotificationDelegate());
MSNotificationHub.SetLifecycleDelegate(new InstallationLifecycleDelegate());
MSNotificationHub.ClearTags();
if (subscriptionTags != null)
foreach (string tag in subscriptionTags)
{
MSNotificationHub.AddTag(tag);
}
var template = new MSInstallationTemplate();
template.Body = AppConstants.APNTemplateBody;
if (subscriptionTags != null)
foreach (string tag in subscriptionTags)
{
template.AddTag(tag);
}
MSNotificationHub.SetTemplate(template, key: "defaultTemplate");
Logger.WriteLine($"SubscribeToAzure: done subscribing routine");
}
catch (Exception e)
{
Logger.WriteLine($"SubscribeToAzure: Whole deal failed, {e.Message}");
}
}
}
public class InstallationLifecycleDelegate : MSInstallationLifecycleDelegate
{
public override void DidFailToSaveInstallation(MSNotificationHub notificationHub, MSInstallation installation, NSError error)
{
Logger.WriteLine($"Subscribing to Azure failed with exception: {error.LocalizedDescription}");
}
public override void DidSaveInstallation(MSNotificationHub notificationHub, MSInstallation installation)
{
RuntimeInfo.AzureSubscribed = true;
Logger.WriteLine($"Subscribed to Azure successfully with Installation ID: {installation.InstallationId}");
}
}
public class NotificationDelegate : MSNotificationHubDelegate
{
public override void DidReceivePushNotification(MSNotificationHub notificationHub, MSNotificationHubMessage message)
{
NSDictionary userInfo = message.UserInfo;
if (UIApplication.SharedApplication.ApplicationState == UIApplicationState.Background)
{
Logger.WriteLine($"Message received in the background with title {message.Title} and body {message.Body}");
ProcessNotification(userInfo, true);
}
else
{
Logger.WriteLine($"Message received in the foreground with title {message.Title} and body {message.Body}");
ProcessNotification(userInfo, true);
}
}
}
Log only shows that all parts of code were passed:
[23.10.2020 18:34:33]: Subscribing to Azure Hub....
[23.10.2020 18:34:33]: SubscribeToAzure: done subscribing routine
Also tried automatic swizzle disabling to log every step, same result.
UPDATE
After few days of struggling, I found out that if execution slips from main thread, iOS blocks requests and Xamarin.Azure.NotificationHubs.iOS wouldn't say anything about it. Running it forcibly in main thread gave it a nudge. Sadly, it still doesn't work.
The first approach with SBNotificationHub failed to register template. Code above do RegisterNative and I get native entry in notification hub. But RegisterTemplate return 'Bad Request'.
[28.10.2020 15:26:10]: RegisterTemplateAsync error: URLRequest failed for <NSMutableURLRequest: 0x282bac6e0> { URL: https://webtutormobile.servicebus.windows.net//Registrations/8635975298502840400-8846379580641729326-3?api-version=2013-04 } with status code: bad request
Second approach with MSNotificatoinHub fail to obtain NSDictionary from MSNotificationHubMessage.UserInfo getter, and breaks on this line:
public override void DidReceivePushNotification(MSNotificationHub notificationHub, MSNotificationHubMessage message)
{
var userInfo = message.UserInfo; // MSNotificationHubMessage.UserInfo has type NSDictionary<NSString, NSString>
with exception:
[28.10.2020 16:22:58]: Received azure notification error: Unable to cast object of type 'Foundation.NSDictionary' to type 'Foundation.NSDictionary`2[[Foundation.NSString, Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065],[Foundation.NSString, Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065]]'