Ian Warburton
Ian Warburton

Reputation: 15676

Determine if app is in foreground upon receiving a push notification

iOS calls void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) upon receiving a push notification regardless of whether the app is not running, in the background or in the foreground.

When it's in the foreground, I want the app to respond differently.

But how do I detect which state it is in?

Upvotes: 7

Views: 5172

Answers (3)

Edward Brey
Edward Brey

Reputation: 41648

Check the application state:

bool isInBackground =
    UIApplication.SharedApplication.ApplicationState == UIApplicationState.Background

Upvotes: 6

GiampaoloGabba
GiampaoloGabba

Reputation: 1458

You can detect when a push notification is tapped using a custom UNUserNotificationCenter in the iOS project, and use the MessagingCenter to speak with the Xamarin.Form shared project.

The custom delegate:

create the file CustomUNUserNotificationCenterDelegate.cs in your Xamarin.iOS project:

using System;
using UserNotifications;
using Xamarin.Forms;

namespace MyApp.iOS
{
    public class CustomUNUserNotificationCenterDelegate : UNUserNotificationCenterDelegate
    {    
        //This will be called when a user tap a notification and the app will be back in foreground
        public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
        {
            if (response.IsDefaultAction)
            {
                // User tapped on notification. Pass the notification body 
               //(maybe its better to make some null check to prevent NRE. I'll skip it in this example
                var response = notification.Request.Content;
                MessagingCenter.Send("MyApp", "pushClicked", response.Body);
            }

            // Complete handling the notification.
            completionHandler();
        }
    }

    //This will be called when the notification is received when the app is in Foreground
    public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    {
        //Notification received
        //(maybe its better to make some null check to prevent NRE. I'll skip it in this example
        var response = notification.Request.Content;
        MessagingCenter.Send("MyApp", "pushReceived", response.Body);

        //Complete handling the notification.
        completionHandler(UNNotificationPresentationOptions.None);
    }
}

Modify your AppDelegate.cs

Add to your AppDelegate.cs this to activate our custom delegate:

    //Custom delegate per gestire le push in foreground/cliccate da background
    if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
    {
        UNUserNotificationCenter.Current.Delegate = new CustomUNUserNotificationCenterDelegate();
    }

The Xamarin.Forms project

In your Xamarin.Forms project you can subscribe to your message and execute arbitrary code:

    //Subscribe to notification tapped when app is closed
    MessagingCenter.Subscribe<string, string> (this, "pushClicked", (sender, args) =>
    {
        //Do something when a push notification is clicked.
        //your notification body will be in the "args" variable
    });

    //Subscrive to notification received when app is in foreground
    MessagingCenter.Subscribe<string, string> (this, "pushReceived", (sender, args) =>
    {
        //Do something when a push notification is clicked.
        // your notification body will be in the "args" variable
    });

Dont forget to unsubscribe from the MessagingCenter when you dont need it anymore or the page/object container is disposed

Upvotes: 2

Jannie Theunissen
Jannie Theunissen

Reputation: 30164

You can monitor the Application lifecycle events:

public partial class App : Xamarin.Forms.Application
{
    public static bool IsInForeground { get; set; } = false;

    protected override void OnStart()
    {
        IsInForeground = true;
    }

    protected override void OnSleep()
    {
        IsInForeground = false;
    }

    protected override void OnResume()
    {
        IsInForeground = true;
    }
}

And then in any of your pages or services check for App.IsInForeground

Upvotes: 12

Related Questions