Home > Blockchain >  Update content of delivered local notification SwiftUI
Update content of delivered local notification SwiftUI

Time:08-21

New to Xcode and Swift. My app has a timer that counts down. I'd like for the countdown to be visible from the lock screen as a notification, but I can't figure out how to (of if it's even possible to) update the content of an existing local notification.

The only solution I've found so far is to cancel the current notification and show a new one every second, which is not ideal.

Code:

struct TimerApp: View {
    private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() 
    @State private var isActive: Bool = true    // whether not timer is active 
    @State private var timeRemaining: Int = 600     // 60 seconds * 10 mins = 10 min-countdown timer

    var body: some View {
        // body stuff
        // toggle isActive if user stops/starts timer

    }.onReceive(timer, perform: { _ in 
        guard isActive else { return }

        if timeRemaining > 0 { 
            // would like to update current notification here
            // *******

            // instead, removing and adding a new one right now
            UNUserNotificationCenter.current().removeAllDeliveredNotifications()
            UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
            addNotification()
 
            timeRemaining -= 1
        } else {
            isActive = false
            timeRemaining = 0
        }
    }

    func addNotification() {
        
        let center = UNUserNotificationCenter.current()

        let addRequest = {
            let content = UNMutableNotificationContent()
            content.title = "App Title"
            content.body = "Time: \(timeFormatted())"
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.0001, repeats: false)

            let request = UNNotificationRequest(identifier: "onlyNotification", content: content, trigger: trigger)
            center.add(request)            
            
        }
        
        center.getNotificationSettings { settings in
            if settings.authorizationStatus == .authorized {
                addRequest()
            } else {
                center.requestAuthorization(options: [.alert, .badge]) { success, error in
                    if success {
                        addRequest()
                    } else if let error = error {
                        print("error :( \(error.localizedDescription)")
                    }
                }
            }
        }
    }

    func timeFormatted() -> String {
        // converts timeRemaining to 00:00 format and returns string
    }
}

And here is what the hilariously bad solution looks like right now.

enter image description here

CodePudding user response:

Currently it's not possible to update a pending or delivered local notification request.

Just like you guessed, in order to deliver a notification with a different content instead, you need to remove the pending request using UNNotificationCenter's methods removePendingNotificationRequests(withIdentifiers:) or removeAllPendingNotificationRequests() and add a new request with the updated content.

  • Related