diff --git a/LeCountdown/Conductor.swift b/LeCountdown/Conductor.swift index f6b1127..8b8e521 100644 --- a/LeCountdown/Conductor.swift +++ b/LeCountdown/Conductor.swift @@ -7,6 +7,7 @@ import Foundation import ActivityKit +import BackgroundTasks class Conductor : ObservableObject { @@ -49,10 +50,10 @@ class Conductor : ObservableObject { if !cancel { self._recordActivity(countdownId: countdownId) } - self.notificationDates.removeValue(forKey: countdownId) -// self._updateLiveActivity(countdownId: countdownId, endDate: <#T##Date#>) - self._endLiveActivity(countdownId: countdownId) + if self.notificationDates.removeValue(forKey: countdownId) != nil { + self._endLiveActivity(countdownId: countdownId) + } } } @@ -114,11 +115,25 @@ class Conductor : ObservableObject { do { let liveActivity = try ActivityKit.Activity.request(attributes: attributes, content: activityContent) - print("Requested a countdown Live Activity \(String(describing: liveActivity.id)).") + print("Requested a Countdown Live Activity: \(String(describing: liveActivity.id)).") } catch (let error) { print("Error requesting countdown Live Activity \(error.localizedDescription).") } + self._scheduleAppRefresh(countdown: countdown) + + } + } + + fileprivate func _scheduleAppRefresh(countdown: Countdown) { + let request = BGAppRefreshTaskRequest(identifier: BGTaskIdentifier.refresh.rawValue) + request.earliestBeginDate = Date(timeIntervalSinceNow: countdown.duration) + + do { + try BGTaskScheduler.shared.submit(request) + print("request submitted with date: \(String(describing: request.earliestBeginDate))") + } catch { + print("Could not schedule app refresh: \(error)") } } @@ -127,25 +142,36 @@ class Conductor : ObservableObject { } func updateLiveActivities() { + print("update live activity...") for (countdownId, interval) in self.notificationDates { - if let activity = self._liveActivity(countdownId: countdownId) { - - Task { - let ended = interval.end < Date() - let state = LaunchWidgetAttributes.ContentState(ended: ended) - let content = ActivityContent(state: state, staleDate: interval.end) - await activity.update(content) - print("Ending the Live Activity: \(activity.id)") - } + + if interval.end < Date() { + self._endLiveActivity(countdownId: countdownId) } + + +// if let activity = self._liveActivity(countdownId: countdownId) { +// +// Task { +// +// if ended { +// self._endLiveActivity(countdownId: countdownId) +// } +// +//// let state = LaunchWidgetAttributes.ContentState(ended: ended) +//// let content = ActivityContent(state: state, staleDate: interval.end) +//// await activity.update(content) +//// print("Ending the Live Activity: \(activity.id)") +// } +// } } } fileprivate func _endLiveActivity(countdownId: String) { - print("Trt to end the Live Activity: \(countdownId)") + print("Try to end the Live Activity: \(countdownId)") if let activity = self._liveActivity(countdownId: countdownId) { Task { diff --git a/LeCountdown/CountdownScheduler.swift b/LeCountdown/CountdownScheduler.swift index dc41d42..cc9362d 100644 --- a/LeCountdown/CountdownScheduler.swift +++ b/LeCountdown/CountdownScheduler.swift @@ -53,7 +53,7 @@ class CountdownScheduler { let duration = countdown.duration let trigger = UNTimeIntervalNotificationTrigger(timeInterval: duration + offset, repeats: false) - let request = UNNotificationRequest(identifier: countdown.objectID.uriRepresentation().absoluteString + "/\(offset)", + let request = UNNotificationRequest(identifier: countdown.objectID.uriRepresentation().absoluteString, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { error in diff --git a/LeCountdown/Info.plist b/LeCountdown/Info.plist index aba22b9..0327e78 100644 --- a/LeCountdown/Info.plist +++ b/LeCountdown/Info.plist @@ -2,6 +2,10 @@ + BGTaskSchedulerPermittedIdentifiers + + com.staxriver.lecountdown.refresh + NSUserActivityTypes SelectCountdownIntent @@ -16,6 +20,7 @@ UIBackgroundModes audio + fetch diff --git a/LeCountdown/LeCountdownApp.swift b/LeCountdown/LeCountdownApp.swift index 2e710c2..24d748b 100644 --- a/LeCountdown/LeCountdownApp.swift +++ b/LeCountdown/LeCountdownApp.swift @@ -6,6 +6,11 @@ // import SwiftUI +import BackgroundTasks + +enum BGTaskIdentifier : String { + case refresh = "com.staxriver.lecountdown.refresh" +} @main struct LeCountdownApp: App { @@ -32,6 +37,8 @@ struct LeCountdownApp: App { } fileprivate func _onAppear() { + self._registerBackgroundRefreshes() + // Task { // for s in Sound.allCases { // do { @@ -43,5 +50,26 @@ struct LeCountdownApp: App { // } // } } + + fileprivate func _registerBackgroundRefreshes() { + BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTaskIdentifier.refresh.rawValue, using: nil) { task in + self._handleAppRefresh(task: task as! BGAppRefreshTask) + } + } + + fileprivate func _handleAppRefresh(task: BGAppRefreshTask) { + + print("_handleAppRefresh = \(task.description)") + + task.expirationHandler = { + print("expired") + } + + DispatchQueue.main.async { + Conductor.maestro.updateLiveActivities() + task.setTaskCompleted(success: true) + } + + } }