0

maybe someone can help me. In my app I'm using push notifications to inform the users that a new message is written to the database. One user can accept the notification and work with the content or dismiss it. If the user accepts it, a silent push is sent to all other devices which received the notification earlier. Here is my code handling this silent notification:

public override void ReceivedRemoteNotification(UIApplication application, NSDictionary remoteNotification)
    {
        try
        {                
            if (remoteNotification != null)
            {
                var alert = remoteNotification[FromObject("aps")];
                if (alert != null)
                {
                    string id = ((NSDictionary)alert)[FromObject("deleteId")].Description;
                    if (!String.IsNullOrEmpty(id))
                    {
                        List<string> idents = new List<string>();

                        UNUserNotificationCenter.Current.GetDeliveredNotifications(completionHandler: (UNNotification[] t) =>
                        {
                            foreach (UNNotification item in t)
                            {
                                UNNotificationRequest curRequest = item.Request;
                                var notificationId = ((NSDictionary)curRequest.Content.UserInfo[FromObject("aps")])[FromObject("notificationId")].Description;
                                if (id == notificationId)
                                {
                                    idents.Add(curRequest.Identifier);
                                }
                            }
                            UNUserNotificationCenter.Current.RemoveDeliveredNotifications(idents.ToArray());
                        });
                    }
                }
            }

        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }

The problem is that the notification is still visible in the notification center until the app is brought to foreground. But then it gets deleted.

Is there a way to force the method to delete the notification instantly and not only when the app is (re)opened?

2 Answers2

0

When you want to clear the Notifications send from this app. Set its application's badge to 0 to achieve this.

As you said you send a silent notifications to other users, Then DidReceiveRemoteNotification() will fire. In this event we can clear all notifications:

public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
    var aps = userInfo["aps"] as NSDictionary;
    if (aps["content-available"].ToString() == "1")
    {
        //check if this is a silent notification.
        UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
    }
    completionHandler(UIBackgroundFetchResult.NewData);
}

Please notice that starting with iOS 8.0, your application needs to register for user notifications to be able to set the application icon badge number. So please add the code below in FinishedLaunching():

UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Badge, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

Moreover silent notifications can only be received when your app is on background or foreground. If it's terminated, this will fail.

Ax1le
  • 6,563
  • 2
  • 14
  • 61
  • 2
    But by setting the badge number to 0, I remove all notifications. That's not what I want. I want to delete one specific notification (the one which the user accepted) on all devices and the other notifications should stay in the notification center. Also, wouldn't it be better to use the `UserNotifications` framework for iOS 11 like I did in my code above? – TheOneThing Mar 22 '18 at 06:39
  • OK, now I konw you want to remove the particular notification. You can put your code in the event `DidReceiveRemoteNotification()` instead of `ReceivedRemoteNotification()`. When device receives silent notifications, `DidReceiveRemoteNotification()` will be called. – Ax1le Mar 22 '18 at 09:30
  • Thank you, now it works. Now I handle my code in the `DidReceiveRemoteNotification()` method – TheOneThing Mar 23 '18 at 07:16
0

To remove a notification, you send a silent push notification to all devices with the notification ID as payload that should be removed.

On the clients you implement a UNNotificationServiceExtension which allows you to remove currently displayed notifications by their IDs: UNUserNotificationCenter.current().removeDeliveredNotifications.

This gives you the advantage that you have full control over this logic on the server side.

Manuel
  • 14,274
  • 6
  • 57
  • 130