import ActivityKit import Foundation @MainActor final class RecordingLiveActivityManager { static let shared = RecordingLiveActivityManager() private var activity: Activity? private init() {} var recoverableSessionID: UUID? { activity?.attributes.sessionID ?? Activity.activities.first?.attributes.sessionID } func start( sessionID: UUID, title: String, sourceName: String, elapsedSeconds: TimeInterval ) { guard ActivityAuthorizationInfo().areActivitiesEnabled else { return } Task { await endExistingActivities() let attributes = RecordingActivityAttributes( sessionID: sessionID, title: title, sourceName: sourceName ) let state = makeState(elapsedSeconds: elapsedSeconds, isPaused: false) do { activity = try Activity.request( attributes: attributes, content: ActivityContent(state: state, staleDate: nil), pushType: nil ) } catch { print("[RecordingLiveActivity] Failed to start: \(error.localizedDescription)") } } } func update(elapsedSeconds: TimeInterval, isPaused: Bool) { guard let activity else { return } let state = makeState(elapsedSeconds: elapsedSeconds, isPaused: isPaused) Task { await activity.update(ActivityContent(state: state, staleDate: nil)) } } func end(elapsedSeconds: TimeInterval) { guard let activity else { return } self.activity = nil let finalState = makeState(elapsedSeconds: elapsedSeconds, isPaused: true) Task { await activity.end( ActivityContent(state: finalState, staleDate: nil), dismissalPolicy: .immediate ) } } private func endExistingActivities() async { for existingActivity in Activity.activities { await existingActivity.end(nil, dismissalPolicy: .immediate) } } private func makeState( elapsedSeconds: TimeInterval, isPaused: Bool ) -> RecordingActivityAttributes.ContentState { RecordingActivityAttributes.ContentState( timerStartDate: Date().addingTimeInterval(-elapsedSeconds), elapsedSeconds: elapsedSeconds, isPaused: isPaused ) } }