Search code examples
iosobjective-capple-push-notificationsuilocalnotification

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


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?


Solution

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