无法在 iOS 上的 Azure NotificationHub 中注册设备,没有回调 [英] Cannot register device in Azure NotificationHub on iOS, no callbacks

查看:52
本文介绍了无法在 iOS 上的 Azure NotificationHub 中注册设备,没有回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 Azure NotificationHub 设置推送通知(使用 这些 指南).Android 运行良好,但 iOS...

无论我做什么,我都没有收到来自 SBNotificationHubRegisterNative/RegisterTemplate 方法的任何回调,并且没有注册出现在枢纽.

我的代码(非常简单):

public static void SubscribeToAzure(NSData deviceToken, string[] subscriptionTags = null, bool bUnsubscribe = false){尝试{var Hub = new SBNotificationHub(AppConstants.ListenConnectionString, AppConstants.NotificationHubName);Logger.WriteLine($"Unsubscribing from AzureHub [{deviceToken}]....");Hub.UnregisterAll(deviceToken, (error) =>{如果(错误!= null){Logger.WriteLine($"SubscribeToAzure: Unable to call unregister, {error}");返回;}RuntimeInfo.AzureSubscribed = false;如果(b取消订阅)返回;Logger.WriteLine($"Register native in AzureHub [{deviceToken}]....");var 标签 = subscriptionTags != null ?new NSSet(subscriptionTags.ToArray()) : new NSSet("default");Hub.RegisterNative(deviceToken, tags, errorCallback =>{//!!!从来没有到过这里!!!如果(错误回调!= null)Logger.WriteLine($"RegisterNative error: {errorCallback}");别的Logger.WriteLine($RegisterNative OK");});Logger.WriteLine(在 AzureHub 中注册模板....");var templateExpiration = DateTime.Now.AddDays(120).ToString(System.Globalization.CultureInfo.CreateSpecificCulture(en-US"));Hub.RegisterTemplate(deviceToken, defaultTemplate", AppConstants.APNTemplateBody, templateExpiration, tags, errorCallback =>{//!!!从来没有到过这里!!!如果(错误回调!= null){Logger.WriteLine($"RegisterTemplateAsync 错误:{errorCallback}");}别的{Logger.WriteLine(已成功订阅 Azure.");RuntimeInfo.AzureSubscribed = true;}});Logger.WriteLine(注册通过....");});}捕获(例外 e){Logger.WriteLine($"SubscribeToAzure: Whole deal failed, {e.Message}");}}

始终获取此日志消息(不调用回调):

<块引用>

[22.10.2020 18:13:43]:取消订阅 AzureHub [{长度 = 32,字节 = 0x342c9bc5 d75ffb0b d68078d0 47e94320 ... e08989c9 676a}.p>...

<块引用>

[22.10.2020 18:13:44]:在 AzureHub 中注册本机 [{length = 32, bytes = 0x342c9bc5 d75ffb0b d68078d0 47e94320 ... e08989c9 66a13a37> }

<块引用>

[22.10.2020 18:13:44]:在 AzureHub 中注册模板....

<块引用>

[22.10.2020 18:13:44]:注册已通过....

中心中没有 iOS 注册.任何地方都没有错误.

我尝试了证书和令牌认证模式,但没有成功.

我对所有证书、状态、密钥、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;如果(b取消订阅){//??}别的{尝试{Logger.WriteLine(订阅 Azure Hub....");MSNotificationHub.Start(AppConstants.ListenConnectionString, AppConstants.NotificationHubName);MSNotificationHub.SetDelegate(new NotificationDelegate());MSNotificationHub.SetLifecycleDelegate(new InstallationLifecycleDelegate());MSNotificationHub.ClearTags();如果(订阅标签!= null)foreach(subscriptionTags 中的字符串标签){MSNotificationHub.AddTag(tag);}var 模板 = 新的 MSInstallationTemplate();template.Body = AppConstants.APNTemplateBody;如果(订阅标签!= null)foreach(subscriptionTags 中的字符串标签){template.AddTag(tag);}MSNotificationHub.SetTemplate(template, key: "defaultTemplate");Logger.WriteLine($"SubscribeToAzure: 完成订阅例程");}捕获(例外 e){Logger.WriteLine($"SubscribeToAzure: Whole deal failed, {e.Message}");}}}公共类 InstallationLifecycleDelegate : MSInstallationLifecycleDelegate{公共覆盖无效 DidFailToSaveInstallation(MSNotificationHub notificationHub, MSInstallation 安装, NSError 错误){Logger.WriteLine($"订阅 Azure 失败,异常:{error.LocalizedDescription}");}公共覆盖无效 DidSaveInstallation(MSNotificationHub notificationHub, MSInstallation 安装){RuntimeInfo.AzureSubscribed = true;Logger.WriteLine($"以安装 ID 成功订阅 Azure:{installation.InstallationId}");}}公共类 NotificationDelegate : MSNotificationHubDelegate{公共覆盖无效 DidReceivePushNotification(MSNotificationHub notificationHub, MSNotificationHubMessage 消息){NSDictionary userInfo = message.UserInfo;如果(UIApplication.SharedApplication.ApplicationState == UIApplicationState.Background){Logger.WriteLine($"在后台收到消息,标题为{message.Title},正文为{message.Body}");ProcessNotification(userInfo, true);}别的{Logger.WriteLine($"在前台收到消息,标题为{message.Title},正文为{message.Body}");ProcessNotification(userInfo, true);}}}

日志只显示代码的所有部分都通过了:

<块引用>

[23.10.2020 18:34:33]:订​​阅 Azure Hub....

<块引用>

[23.10.2020 18:34:33]:SubscribeToAzure:完成订阅程序

还尝试了自动 swizzle 禁用 来记录每一步,同样的结果.


更新

经过几天的努力,我发现如果执行从主线程滑出,iOS 会阻止请求,而 Xamarin.Azure.NotificationHubs.iOS 不会对此进行任何说明.在主线程中强行运行它给了它一个推动.遗憾的是,它仍然不起作用.

使用 SBNotificationHub 的第一种方法未能注册模板.上面的代码执行 RegisterNative 并且我在通知中心获得本机条目.但是 RegisterTemplate 返回错误请求".

<块引用>

[28.10.2020 15:26:10]:RegisterTemplateAsync 错误: 的 URLRequest 失败{ URL:https://webtutormobile.servicebus.windows.net//Registrations/8635975298502840400-8846379580664172932-3?api-version=2013-04 } 带有状态码:错误请求

使用 MSNotificatoinHub 的第二种方法无法从 MSNotificationHubMessage.UserInfo getter 获取 NSDictionary,并在此行中断:

public override void DidReceivePushNotification(MSNotificationHub notificationHub, MSNotificationHubMessage message){var userInfo = message.UserInfo;//MSNotificationHubMessage.UserInfo 的类型为 NSDictionary

例外:

<块引用>

[28.10.2020 16:22:58]:收到天蓝色通知错误:无法将Foundation.NSDictionary"类型的对象转换为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]]'

解决方案

终于有了结论.如果有人感兴趣:

  1. 集线器注册必须在主线程中调用.否则 Xamarin.Azure.NotificationHubs.iOS 甚至不会提示出现问题.

  2. MSNotificationHub 的新方法在将 UserInfo 转换为 NSDictionary 时在获取 UserInfo 时存在错误.当实际类型为 NSDictionary 时.现在在GitHub上发布了一段时间,但仍然没有团队的任何回应,所以如果你通过推送通知传递除了消息之外的任何数据,对不起,这是不行的.

  3. 使用 SBNotificationHub 的旧方法具有严格的模板格式.首先,您应该使用输出错误的 RegisterTemplate 方法,而不是执行回调的方法,因为前者是唯一出于某种原因给出错误描述的方法.其次,您不能使用 {$(field)} 构造来定义模板,您需要为属性指定插入格式,例如:"alert":"$(messageParam)","badge":"#(badge)","content-available":"#(contentAvailable)" 等.此外,您还需要修改调度程序,以便它始终发送未引用的参数.

IOS 实现非常原始、半成品和被遗忘.我知道与 Apple 的互动是彻底的地狱和痛苦,但仍然......

希望它能为某人节省大量时间.

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]]'

解决方案

Finally it has been brought to conclusion. If anyone's interested:

  1. Hub Registrations must be called in main thread. Otherwise Xamarin.Azure.NotificationHubs.iOS wouldn't even give a hint that something went wrong.

  2. New approach with MSNotificationHub has a bug in getting UserInfo with casting it to NSDictionary<NSString, NSString> when actual type is NSDictionary. It is issued in GitHub for a while now, but still without any response from team, so if you pass any data besides message through push notification, sorry, it's no go.

  3. Old approach using SBNotificationHub has strict Template format. First of all, you shoud use RegisterTemplate method that outs error, not one that do callback, as the former one is the only that gives error description for some reason. Secondly, you can't define template using {$(field)} constructon, you need to specify insertion format for properties, like: "alert":"$(messageParam)","badge":"#(badge)","content-available":"#(contentAvailable)" etc. Also you need to modify dispatcher so it would always send unquoted parameters.

IOS implementation is extremely raw, half-done and forgotten. I understand that interacting with Apple is utter hell and pain in the rear, but still...

Hope it saves someone lots and lots of time.

这篇关于无法在 iOS 上的 Azure NotificationHub 中注册设备,没有回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆