Set timeout for UILocalNotification (remove it from lockscreen and notification center after some time)
Asked Answered
C

2

7

I would like to set a UILocalNotification that will disappear from the lock screen and the notification center after five minutes (if the user won't tap on it).

Can I set a timeout for the notification? Or maybe fire another notification that will delete it?

Candelabrum answered 29/4, 2014 at 12:24 Comment(1)
Any news or ideas on this issue, I swear I've seen the Facebook app do this however I cannot find anything online?Corrugation
C
0

Disclaimer: The code will work only if you wake the app. In my case this code is called from application(_:handleActionWithIdentifier:for:completionHandler:), which is triggered from a local notification, which in its turn is called from a bluetooth beacon monitoring. So that entering the bluetooth beacon's range wakes the app for me. What will be waking the app your case is up to you - this can be a silent notification form your backend, for example. Also I doubt that iOS would let the timer to run for 5 mins, in my case the 20 seconds timer fires with very high probability (though I understand that it is not 100% guaranteed and sometimes notification might remain, however it is not crucial in my case).

Closing the notification in 20 seconds:

if #available(iOS 10.0, *) {
    ... <setting up an iOS 10 notification content and trigger>
    notificationCenter.add(UNNotificationRequest(identifier: "myidentifier", 
                                                content: content, 
                                                trigger: trigger))
    Timer.scheduledTimer(timeInterval: 20.0, 
                               target: self, 
                             selector: #selector(self.cancelDeliveredNotification), 
                             userInfo: nil, 
                              repeats: false)
} else {
    let notification = UILocalNotification()
    ... <setting up an iOS8/9 notification>
    Timer.scheduledTimer(timeInterval: 20.0, 
                               target: self, 
                             selector: #selector(self.cancelDeliveredNotification), 
                             userInfo: notification as Any?, 
                              repeats: false)

the cancelling function:

func cancelDeliveredNotification(_ sender: Timer) {
    if #available(iOS 10.0, *) {
         UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["myidentifier"])
    } else {
         if let notificationToCancel = sender.userInfo as? UILocalNotification {
             UIApplication.shared.cancelLocalNotification(notificationToCancel)
    }
}

alternatively you can also do UNUserNotificationCenter.current().removeAllDeliveredNotifications()

Cosignatory answered 20/7, 2017 at 15:6 Comment(0)
A
2

I believe Facebook does this by sending a silent push notification from their servers that triggers this code in the app:

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];

To keep the solution entirely local to the device, you can set an NSTimer that can then trigger the above code at the proper interval. This comes with the huge caveat that if your app is suspended when in the background your timer won't fire until it is brought back an active state.

Assyrian answered 18/4, 2015 at 4:44 Comment(2)
This answer really only addresses notifications sent/removed while the app is active, which doesn't apply to many use cases. Perhaps the Timer could be called from a service extension instead?Toh
For people wondering why Facebook would do that - you receive a push notification about a new message from a friend on your device, but it’s cleared automatically if you read it on your desktop without any interaction with an iOS app.Silicify
C
0

Disclaimer: The code will work only if you wake the app. In my case this code is called from application(_:handleActionWithIdentifier:for:completionHandler:), which is triggered from a local notification, which in its turn is called from a bluetooth beacon monitoring. So that entering the bluetooth beacon's range wakes the app for me. What will be waking the app your case is up to you - this can be a silent notification form your backend, for example. Also I doubt that iOS would let the timer to run for 5 mins, in my case the 20 seconds timer fires with very high probability (though I understand that it is not 100% guaranteed and sometimes notification might remain, however it is not crucial in my case).

Closing the notification in 20 seconds:

if #available(iOS 10.0, *) {
    ... <setting up an iOS 10 notification content and trigger>
    notificationCenter.add(UNNotificationRequest(identifier: "myidentifier", 
                                                content: content, 
                                                trigger: trigger))
    Timer.scheduledTimer(timeInterval: 20.0, 
                               target: self, 
                             selector: #selector(self.cancelDeliveredNotification), 
                             userInfo: nil, 
                              repeats: false)
} else {
    let notification = UILocalNotification()
    ... <setting up an iOS8/9 notification>
    Timer.scheduledTimer(timeInterval: 20.0, 
                               target: self, 
                             selector: #selector(self.cancelDeliveredNotification), 
                             userInfo: notification as Any?, 
                              repeats: false)

the cancelling function:

func cancelDeliveredNotification(_ sender: Timer) {
    if #available(iOS 10.0, *) {
         UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["myidentifier"])
    } else {
         if let notificationToCancel = sender.userInfo as? UILocalNotification {
             UIApplication.shared.cancelLocalNotification(notificationToCancel)
    }
}

alternatively you can also do UNUserNotificationCenter.current().removeAllDeliveredNotifications()

Cosignatory answered 20/7, 2017 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.