Forum Xamarin.Mac

How to return a notification status from UNUserNotificationCenter.Current.GetNotificationSettings()?

CCantCCant GBMember ✭✭

Hi all, I am trying to get the notification status of the application (i.e. I want to know whether the user has approved notifications for the App or not). I believe that the way to do this is to use the UNUserNotificationCenter.Current.GetNotificationSettings() method. However, when I run the following code it appears that the 'registered' variable is returned before the 'completionHandler' action is run.

        public bool RegisteredForNotifications()
        {
            bool registered = false;

                UNUserNotificationCenter.Current.GetNotificationSettings(completionHandler: (settings) =>
                {
                    // This if statement runs after the return, so this method always returns false;
                    if (settings.AuthorizationStatus == UNAuthorizationStatus.Authorized)
                    {
                        registered = true;
                    }
                });

            return registered;
        }

Please note that this method is called during startup as well as when you navigate onto a settings page within the app and it is called using a property:

               public static bool AreNotifcationsAllowed
                {
                    get => DependencyService.Get<INotificationsInterface>().RegisteredForNotifications();
                }

Any idea on how to get the result from GetNotificationSettings() prior to the method completing?
Thanks in advance.

Best Answer

Answers

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    You misunderstand how that API works:

    https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/1649524-getnotificationsettingswithcompl?language=objc

    GetNotificationSettings does not synchronously return, it calls the completion handler with the value. This means code that needs to know the value also has to be async.

    See https://docs.microsoft.com/en-us/xamarin/cross-platform/platform/async for an introduction to the concept.

  • CCantCCant GBMember ✭✭

    Hi @ChrisHamons thank you very much for your reply. I am fairly new to async programming but I do understand the majority of the basic concepts but when I have been doing this I have not really dealt with voids. If that method returned a Task I would be know exactly how to deal with it but you cannot await voids. Async methods that return voids effectively run synchronously when you call them from an async method which is all very well until you realise the completion handler within the async void method runs asynchronously - there is no way to wait on that completing. I have tried putting the above code in a Async method and running it from a synchronous method (as I have not yet figured out how to call a async method from a property):

    Task myTask = Task.Run(() => RegisteredForNotificationsAsync() ;
    myTask.Wait();
    

    but that does the same thing. It waits for the GetNotificationSettings() method but not for the action within that method to complete.

    I am probably missing a key piece of the puzzle so any help is appreciated.

    Thanks

  • CCantCCant GBMember ✭✭

    Thank you @ChrisHammond! I didn't realise that I could take the settings out into a variable and await it that way. It is working now (well apart from during the startup code but that another issue - it is either an async issue or the fact something hasn't been initialised yet). Thank you very much for your help.

Sign In or Register to comment.