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)
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:
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.
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With