我正在尝试通过 Azure NotificationHub 设置推送通知(使用 these guides )。 Android 运行良好,但 iOS...
无论我做什么,我都没有收到来自 SBNotificationHub 的 RegisterNative/RegisterTemplate 方法的任何回调,并且没有注册出现在中心。
我的代码(非常简单):
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}");
}
}
始终获取此日志消息(不调用回调):
[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....
并且中心中没有 iOS 注册。并且任何地方都没有错误。
我尝试了证书和 token 身份验证模式,但没有成功。
我对所有证书、状态、 key 、ID 等进行了双重、三重和四重检查。
使用 iOS SDK 14.0、iPhone X iOS 14.0.1、Xamarin Forms 4.8.0.1560、Xamarin.Azure.NotificationHubs.iOS 3.1.0。
=======
有人建议我从 SBNotificationHub 迁移到 MSNotificationHub 。
得到完全相同的结果:无论是否出现问题都没有响应。并且中心没有注册。
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);
}
}
}
日志仅显示代码的所有部分都已通过:
[23.10.2020 18:34:33]: Subscribing to Azure Hub....
[23.10.2020 18:34:33]: SubscribeToAzure: done subscribing routine
还尝试过自动 swizzle disabling记录每一步,结果相同。
更新
经过几天的努力,我发现如果执行从主线程中滑落,iOS 会阻止请求,并且 Xamarin.Azure.NotificationHubs.iOS 不会对此做出任何说明。在主线程中强制运行它给了它一个插入。 遗憾的是,它仍然不起作用。
使用SBNotificationHub的第一种方法无法注册模板。上面的代码执行 RegisterNative 操作,我在通知中心获得了 native 条目。但 RegisterTemplate 返回“错误请求”。
[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
使用 MSNotificatoinHub 的第二种方法无法从 MSNotificationHubMessage.UserInfo getter 获取 NSDictionary,并在此行中断:
public override void DidReceivePushNotification(MSNotificationHub notificationHub, MSNotificationHubMessage message)
{
var userInfo = message.UserInfo; // MSNotificationHubMessage.UserInfo has type NSDictionary<NSString, NSString>
异常(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]]'
最佳答案
终于有了结论。如果有人感兴趣:
集线器注册必须在主线程中调用。否则Xamarin.Azure.NotificationHubs.iOS甚至不会给出出现问题的提示。
当实际类型为 NSDictionary 时,MSNotificationHub 的新方法在获取 UserInfo 并将其转换为 NSDictionary
时存在错误。目前在 GitHub 上发布有一段时间了,但团队还没有任何回应,所以如果你通过推送通知传递除消息之外的任何数据,抱歉,不行。 使用SBNotificationHub的旧方法具有严格的模板格式。首先,您应该使用 RegisterTemplate 方法来输出错误,而不是回调方法,因为前一个方法是唯一因某种原因给出错误描述的方法。 其次,您不能使用 {$(field)} 构造函数定义模板,您需要指定属性的插入格式,例如:"alert":"$(messageParam)","badge":"#(badge)","content-available":"#(contentAvailable)" 等。此外,您还需要修改调度程序,以便它始终发送不带引号的参数。
IOS 的实现非常原始、半成品和被遗忘。我知道与苹果互动是彻头彻尾的 hell 和痛苦,但仍然......
希望它可以为人们节省很多很多时间。
关于ios - 无法在 iOS 上的 Azure NotificationHub 中注册设备,无回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64513220/