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()