Forum Xamarin.iOS

Problem when after clicking on notification when app is closed

alex2a7alex2a7 Member ✭✭
edited February 21 in Xamarin.iOS

Hello,
I have created an application cross-platform with a masterDetailView. Then I have implemented azure notification hub to have notification with a rest API to send them. In the payload I put a keyword named action to know what DetailPage I will open.
For that in the ProcessNotification I do that :

void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
        {
    UIAlertView avAlert = new UIAlertView("Notification", "test", null, "OK", null);
                avAlert.Show();
            // 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;
                NSDictionary custum = options.ObjectForKey(new NSString("action")) as NSDictionary;

                string payload = string.Empty;
                NSString alert = new NSString("alert");

                NSString title = new NSString("title");
                NSString message = new NSString("body");
                NSString link = new NSString("url");
                string url = string.Empty;
                NSString action = new NSString("action");

                Debug.WriteLine("coucou" + alert);

                if (aps.ContainsKey(action))
                {
                    payload = aps[action].ToString();
                }
                else if (aps.ContainsKey(link))
                {
                    payload = "url";
                    url = aps[link].ToString();
                }
                if (!fromFinishedLaunching)
                {
                    if (!string.IsNullOrWhiteSpace(payload))
                    {


                        if (payload == "trafic")
                        {
                            Xamarin.Forms.NavigationPage np = ((Xamarin.Forms.NavigationPage)((Xamarin.Forms.MasterDetailPage)App.Current.MainPage).Detail);
                            np.PushAsync(new TraficolorPage());
                        }
                        else if (payload == "webcam")
                        {
                            Xamarin.Forms.NavigationPage np = ((Xamarin.Forms.NavigationPage)((Xamarin.Forms.MasterDetailPage)App.Current.MainPage).Detail);
                            np.PushAsync(new CamPage());
                        }
                        else if (payload == "url")
                        {

                        }


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

It works perfectly In Android but in iOS it works only if the application is in background or not closed. If I kill it, the application open on the main page and seems that it doesn't go in the function above because I have put an alert at the beginning of the function and it doesn't show up.

I followed the tutorial https://docs.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-ios-push-notification-apns-get-started but I don't know why it doesn't works. If there somebody to help me please

Best Answer

  • alex2a7alex2a7 ✭✭
    Accepted Answer

    I have forgotten the method didReceiveRemoteNotification : --"

    public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
            {
                ProcessNotification(userInfo, false);
            }
    

Answers

  • chetanrawatchetanrawat USMember ✭✭✭

    var nav = ((App.Current.MainPage as MenuPage).Detail as NavigationPage).Navigation;
    if (!(nav.NavigationStack[nav.NavigationStack.Count - 1] is Core.Pages.Alerts.PatientAlert))
    {
    nav.PushAsync(new Core.Pages.Alerts.PatientAlert());
    }

  • alex2a7alex2a7 Member ✭✭

    The problem is not here.
    All the code for the above function works only if the application is in the background or open. If I close the application completely (ie by killing the process) and click on the notification it just opens the application on the main view, even the alert (created just for testing) which is at the beginning of the function is not called. I feel that when the app is killed it does not use this function.
    Here is the complete code of the appDelegate:

    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
        {
            private SBNotificationHub Hub { get; set; }
            //
            // 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.
            //
            public override bool FinishedLaunching(UIApplication app, NSDictionary options)
            {
                global::Xamarin.Forms.Forms.Init();
                LoadApplication(new App());
    
                RegisterForRemoteNotifications();
                return base.FinishedLaunching(app, options);
            }
    
            void RegisterForRemoteNotifications()
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
                {
                    UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | 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);
    
                Hub.UnregisterAll(deviceToken, (error) => {
                    if (error != null)
                    {
                        System.Diagnostics.Debug.WriteLine("Error calling Unregister: {0}", error.ToString());
                        return;
                    }
    
                    NSSet tags = null; // create tags if you want
    
                    Hub.RegisterNative(deviceToken, tags, (errorCallback) => {
                        if (errorCallback != null)
                            System.Diagnostics.Debug.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
                    });
                });
            }
    
            public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
            {
                ProcessNotification(userInfo, true);
            }
    
    
            void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
            {
                this.showAlert("Notif", "test");
    
                // 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;
                    NSDictionary custum = options.ObjectForKey(new NSString("action")) as NSDictionary;
    
                    string payload = string.Empty;
                    NSString alert = new NSString("alert");
    
                    NSString title = new NSString("title");
                    NSString message = new NSString("body");
                    NSString link = new NSString("url");
                    string url = string.Empty;
                    NSString action = new NSString("action");
    
                    Debug.WriteLine("coucou" + alert);
    
                    if (aps.ContainsKey(action))
                    {
                        payload = aps[action].ToString();
                    }
                    else if (aps.ContainsKey(link))
                    {
                        payload = "url";
                        url = aps[link].ToString();
                    }
    
                    if (!fromFinishedLaunching)
                    {
                        if (!string.IsNullOrWhiteSpace(payload))
                        {
    
    
                            if (payload == "trafic")
                            {
                                Xamarin.Forms.NavigationPage np = ((Xamarin.Forms.NavigationPage)((Xamarin.Forms.MasterDetailPage)App.Current.MainPage).Detail);
                                np.PushAsync(new TraficolorPage());
                            }
                            else if (payload == "webcam")
                            {
                                Xamarin.Forms.NavigationPage np = ((Xamarin.Forms.NavigationPage)((Xamarin.Forms.MasterDetailPage)App.Current.MainPage).Detail);
                                np.PushAsync(new CamPage());
                            }
                            else if (payload == "url")
                            {
    
                            }
    
    
                            Debug.WriteLine(payload);
                        }
                    }
                }
                else
                {
    
                    Debug.WriteLine($"Received request to process notification but there was no payload.");
    
                }
            }
    
            private void showAlert(string title, string message)
            {
                var okCancelAlertController = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
    
    
                okCancelAlertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, alert => Console.WriteLine("Okay was clicked")));
    
                okCancelAlertController.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, alert => Console.WriteLine("Cancel was clicked")));
                UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(okCancelAlertController, true, null);
    
            }
        }
    
  • alex2a7alex2a7 Member ✭✭
    Accepted Answer

    I have forgotten the method didReceiveRemoteNotification : --"

    public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
            {
                ProcessNotification(userInfo, false);
            }
    
Sign In or Register to comment.