Local notification not presenting when app is in background in Xamarin iOS

Viewed 836

I have implemented chat functionality in my Xamarin.IOS app, as remote notifications are not possible to send from the server-side, I am using local notification to alert the user of new incoming messages. Everything works fine in the simulator, I can see notifications are displayed in the foreground as well as in background mode.

But when I run the app on the device, notification is only working in foreground mode. When the app is in the background, notifications won't show.

After investigating this issue I found that they work fine when the app is running in debug mode(i.e. launched from VisualStudio and cable still attached). But as soon as I disconnect the cable, they won't show anymore.

I have found a few posts https://stackoverflow.com/a/35029847 which suggested that this line would fix the issue, but it won't work since handler cant be null anymore. application.BeginBackgroundTask("showNotification", expirationHandler: null);

So I implemented the below code in my app delegate but it still not working

nint taskID = 111;
            taskID = application.BeginBackgroundTask("showNotification", expirationHandler: ()=> {
                UIApplication.SharedApplication.EndBackgroundTask(taskID);
            });

I also tried Background fetch and added below the line in AppDelegate, but it didn't work. application.SetMinimumBackgroundFetchInterval(UIApplication.BackgroundFetchIntervalMinimum);

Schedule Local Notification code

var content = new UNMutableNotificationContent();
            content.Body = body;
            content.Sound = UNNotificationSound.Default;
            content.UserInfo = dict;
            content.Badge = IOSAppConstant.LocalNotificationCount + 1;

            var request = UNNotificationRequest.FromIdentifier(chatID, content, null);

            // schedule it
            UNUserNotificationCenter.Current.AddNotificationRequest(request, (error) =>
            {
                if (error != null)
                {
                    Console.WriteLine($"Error: {error.LocalizedDescription ?? ""}");
                }
                else
                {
                    Console.WriteLine("Scheduled...");
                }
            });

//Register notification

UNUserNotificationCenter.Current.RequestAuthorization
                (UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound,
                                                                    (granted, error) =>
                                                                    {
                                                                        if (granted)
                                                                            InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
                                                                    });

//Assign Delegate

this._userNotificationCenterDelegate = new UserNotificationCenterDelegate();
UNUserNotificationCenter.Current.Delegate = this._userNotificationCenterDelegate;

//Notification Delegate

public class UserNotificationCenterDelegate : UNUserNotificationCenterDelegate
{
     public override void WillPresentNotification(UNUserNotificationCenter center, 
     UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
     {
          completionHandler(UNNotificationPresentationOptions.Alert);
     }

     public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, 
     UNNotificationResponse response, Action completionHandler)
     {
          completionHandler();
     }
}

I have also tried calling schedule Notification function from BeginBackgroundTask on my chat controller but it is not working

The issue is similar to Local Push notification not working in Xamarin iOS but there is no solution available.

1 Answers

You mentioned that you couldn't use the answer in this question https://stackoverflow.com/a/3502984 because you can't provide null for expirationHandler for BeginBackgroundTask. To get past this you can provide an arbitrary action. The result is that local notifications should work when the released app is in the background

public void NotifAction()
        {
            // This exists because expirationHandler can't be null
        }

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {

            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(UIApplication.BackgroundFetchIntervalMinimum);

            Action testActon = NotifAction;

            UIApplication.SharedApplication.BeginBackgroundTask("showNotification", testActon);
            return base.FinishedLaunching(app, options);
        }
Related