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.
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.