Azure-docs: ReceivedRemoteNotification not triggered.

Created on 14 Jul 2020  Â·  11Comments  Â·  Source: MicrosoftDocs/azure-docs

On item: 11. In AppDelegate.cs, override the ReceivedRemoteNotification() method:

This ReceivedRemoteNotification method is not triggered. Instead the DidReceiveRemoteNotification method is triggered.

Also, instead of just passing in true to the ProcessNotification method. It is better to use the application parameter.

public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
    ProcessNotification(userInfo, application.ApplicationState == UIApplicationState.Active);
}

The parameter fromFinishedLaunching is also confusing: void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)

It would be better named appIsInForeground.


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Pri2 assigned-to-author doc-enhancement doc-idea notification-hubsvc triaged

All 11 comments

Thanks for the feedback @c-lamont! I have assigned the issue to the content author to investigate further and update the document as appropriate.

cc @sethmanheim

Question for you though @c-lamont, what version of the Xamarin iOS SDK are you using?

Question for you though @c-lamont, what version of the Xamarin iOS SDK are you using?

Hi Ryan, I am using v13.18.2.1

@c-lamont please email us at _AzCommunity[at]microsoft[dot]com_ ATTN Ryan mentioning this thread so we can work more closely with you.

Per our conversation @c-lamont, you were able to get your application to call the RecievedRemoteNotification override. One thing to note is that the current OOB template for Single Page iOS app doesn't inherit UIApplciationDelegate for AppDelegate which leads to compile issue. I know you inherited from MvxApplicationDelegate and I didn't notice anything that would prevent RecievedRemoteNotification from being called. However, I will call out that decorating the method with [Export("application:didReceiveRemoteNotification:")] tells the native code to call that method. I'm not sure if you were aware of that or not.

Nonetheless, glad to know you're no longer blocked.

I have the same problem. I decorate the method with [Export("application:didReceiveRemoteNotification:")] but it is not triggered. What may I try to do?

@damar3 You should override ReceivedRemoteNotification without any decoration.

I removed decoration but it is not triggered. When the app is not in foreground I receive notify (but not debug). This is my code:

`using Syncfusion.XForms.iOS.Graphics;
using Syncfusion.XForms.iOS.Border;
using Syncfusion.XForms.iOS.Buttons;
using System;
using System.Collections.Generic;
using System.Linq;
using Syncfusion.SfCalendar.XForms.iOS;

using Foundation;
using UIKit;
using Syncfusion.SfNavigationDrawer.XForms.iOS;
using Syncfusion.ListView.XForms.iOS;
using Syncfusion.SfPicker.XForms.iOS;
using WindowsAzure.Messaging;
using UserNotifications;
using Xamarin.Forms;
using PrenotazioniMobile.Views;

namespace PrenotazioniMobile.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
private SBNotificationHub Hub { get; set; }
public string DeviceToken { get; set; }
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
SfNavigationDrawerRenderer.Init();
SfListViewRenderer.Init();
SfPickerRenderer.Init();
SfGradientViewRenderer.Init();
SfBorderRenderer.Init();
SfButtonRenderer.Init();
SfCalendarRenderer.Init();

        //Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init();
        ProcessNotification(options, false);
        RegisterForRemoteNotifications();

        LoadApplication(new App());
        //base.FinishedLaunching(app, options);           


        //return true;

        return base.FinishedLaunching(app, options);
    }

    void RegisterForRemoteNotifications()
    {
        // register for remote notifications based on system version
        if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
        {
            UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert |
                UNAuthorizationOptions.Sound |
                UNAuthorizationOptions.Sound,
                (granted, error) =>
                {
                    if (granted)
                        InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
                });


        }
        else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
        {
            var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
            UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
            new NSSet());

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

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);

        // update registration with Azure Notification Hub
        Hub.UnregisterAll(deviceToken, (error) =>
        {
            if (error != null)
            {
                //Debug.WriteLine($"Unable to call unregister {error}");
                return;
            }

            var tags = new NSSet(Constants.SubscriptionTags.ToArray());
            //byte[] bytes = deviceToken.ToArray<byte>();
            //string[] hexArray = bytes.Select(b => b.ToString("x2")).ToArray();
            //DeviceToken = string.Join(string.Empty, hexArray);
            Hub.RegisterNative(deviceToken, tags, (errorCallback1) =>
            {
                if (errorCallback1 != null)
                {
                    //Debug.WriteLine($"RegisterNativeAsync error: {errorCallback}");
                }
            });

            var templateExpiration = DateTime.Now.AddDays(120).ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));
            Hub.RegisterTemplate(deviceToken, "defaultTemplate", Constants.APNTemplateBody, templateExpiration, tags, (errorCallback) =>
            {
                if (errorCallback != null)
                {
                    if (errorCallback != null)
                    {
                        //Debug.WriteLine($"RegisterTemplateAsync error: {errorCallback}");
                    }
                }
            });
        });
    }

    // Something went wrong while registering!

    public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
    {
        ProcessNotification(userInfo, false);
    }

    void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
    {                        
        // make sure we have a payload
        if (options != null && options.ContainsKey(new NSString("aps")))
        {
            // get the APS dictionary and extract message payload. Message JSON will be converted
            // into a NSDictionary so more complex payloads may require more processing
            NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
            string payload = string.Empty;
            string body = string.Empty;
            string title = string.Empty;
            NSString payloadKey = new NSString("alert");
            NSString payloadKeyBody = new NSString("body");
            NSString payloadKeyTitle = new NSString("title");
            if (aps.ContainsKey(payloadKey))
            {
                //payload = aps[payloadKey].ToString();
                NSDictionary alert = options.ObjectForKey(aps[payloadKey]) as NSDictionary;
                if (alert.ContainsKey(payloadKeyBody))
                    body = alert[payloadKeyBody].ToString();
                if (alert.ContainsKey(payloadKeyTitle))
                    title = alert[payloadKeyTitle].ToString();
                // bisogna capire come trattare il payload e come prendere i valori che ci interessano


            }

            if (!string.IsNullOrEmpty(title) && !string.IsNullOrEmpty(body))
            {
                //(App.Current.MainPage as MainPage)?.AddMessage(payload);
                SendMessageToMainPage(title, body);
            }

        }
        else
        {
            //Debug.WriteLine($"Received request to process notification but there was no payload.");
        }
    }

    public void SendMessageToMainPage(string titolo, string message)
    {
        NavigationPage myPage = (NavigationPage)App.Current.MainPage;
        MainPageNavigationDefault myPageDefault = (MainPageNavigationDefault)myPage.RootPage;

        //MainPageNavigationDefault myPageDefault = myPage;
        if (myPageDefault != null)
        {
            myPageDefault.AddMessage(titolo, message);
        }
        //(App.Current.MainPage as NavigationPage)?.AddMessage(message);
    }
}

}
`

I'm having this problem too. DidReceiveRemoteNotification is called, but ReceivedRemoteNotification is not called. I easily (after a lot of debugging, web searching, etc) worked around this by adding:

c# [Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")] public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler) => ProcessNotification(userInfo);

@Qythyx I found out that you can only override one or the other. Overriding DidReceiveRemoteNotification means ReceivedRemoteNotification is not called (If I remember correctly).
Maybe this helps @damar3 as well?

@c-lamont, thanks for the info, but for me I originally was only overriding ReceivedRemoteNotification, but it wasn't being called. I then added the override for DidReceiveRemoteNotification and it did get called. The only real difference is that for the Did call I added the decoration, but for the first I did not. I don't know if that matters.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JamesDLD picture JamesDLD  Â·  3Comments

bityob picture bityob  Â·  3Comments

jamesgallagher-ie picture jamesgallagher-ie  Â·  3Comments

bdcoder2 picture bdcoder2  Â·  3Comments

DeepPuddles picture DeepPuddles  Â·  3Comments