Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dismiss 3D-touched notification with custom action?

I am implementing a kind of alert notification for my app, using UserNotifications. When 3D-touching this notification, I want it to display some 'alert information', and the option to "Snooze" the alert, which will effectively repeat the notification in 5 minutes. This is all working fine, except that the notification doesn't get dismissed when I click the Snooze button.

I am using a NotificationContentExtension to modify the content, with the categoryIdentifier "ReminderNotificationExtensionCategory". Then I have created my category in code like this:

let snooze = UNNotificationAction(identifier: "snoozeActionIdentifier", title: NSLocalizedString("SNOOZE", comment: ""), options: .foreground)
let reminderCategory = UNNotificationCategory(identifier: "ReminderNotificationExtensionCategory", actions: [snooze], intentIdentifiers: [], options: .customDismissAction)

UNUserNotificationCenter.current().setNotificationCategories([reminderCategory])//Not sure if I should set this every time or just once..

Then I create my notification object

let content = UNMutableNotificationContent()        
content.categoryIdentifier = "ReminderNotificationExtensionCategory"
content.title = "test"
content.body = "test"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false) //Fire in 3 seconds
let request = UNNotificationRequest(identifier: "someIdentifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error:Error?) in /**/}

Now, my notification will be sent in 3 seconds. I lock my screen and receive it, and it looks great. When I 3D-touch it, my extension is launched, and I get a sneak peak on a UIView I have set up, along with my "Snooze"-button below the notification, as shown in the image:(content removed)Notification

When I click the "Snooze"-button, a UNNotificationContentExtension delegate-method will be called, specifically func didReceive(_ response: completion:) The completion only accepts a value of UNNotificationContentExtensionResponseOption, which would be either .dismiss, .doNotDismiss, or .dismissAndForwardAction. Just for testing, I have done this:

func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
    print("This is happening. ActionIdentifier: ", response.actionIdentifier)
    completion(.dismiss)
}

And when I debug the notification extension, the print does really happen. It prints out "This is happening. ActionIdentifier: snoozeActionIdentifier". However, the notification is not being dismissed. If I change from .dismiss to .doNotDismiss, nothing changes. It still does not dismiss. If I change to .dismissAndForwardAction, it dismisses and opens my app.

I can't find anyone with this problem. I want .dismiss to dismiss my notification. Why isn't it? Am I doing something wrong?

Edit I see now that these two scenarios are happening:

  1. I 3D-touch my notification from the lock screen, then tap outside it, my notification 'collapses' and the regular notification is visible as it was before I 3D-touched it.

  2. I 3D-touch my notification from the lock screen, tap 'Snooze' (and nothing happens), then tap outside the notification, and the regular notification disappears.

So the completion callback actually does dismiss the regular notification, but not the extension. Why? How can I dismiss the extension? Is that a manual method I must call?

like image 748
Sti Avatar asked Jan 30 '23 03:01

Sti


1 Answers

I see my stupid mistake now..

As you can see in my code above, I have instantiated the action button in my category as such:

let snooze = UNNotificationAction(identifier: "snoozeActionIdentifier", title: NSLocalizedString("SNOOZE", comment: ""), options: .foreground)

At the very end, I specify the option .foreground. This should simply be an empty array [] for my purpose.

I thought I had to specify an option, and that the input type was of UNNotificationActionOptions, which only had the options .authenticationRequired ("no I don't want that") .destructive ("no I don't want a red button") and .foreground ("well, if I have to pick one if these.."). Turns out that simply specifying an empty array [] did the trick.

like image 146
Sti Avatar answered Feb 05 '23 14:02

Sti