RecordingLiveActivityManager.swift 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import ActivityKit
  2. import Foundation
  3. @MainActor
  4. final class RecordingLiveActivityManager {
  5. static let shared = RecordingLiveActivityManager()
  6. private var activity: Activity<RecordingActivityAttributes>?
  7. private init() {}
  8. func start(
  9. sessionID: UUID,
  10. title: String,
  11. sourceName: String,
  12. elapsedSeconds: TimeInterval
  13. ) {
  14. guard ActivityAuthorizationInfo().areActivitiesEnabled else { return }
  15. Task {
  16. await endExistingActivities()
  17. let attributes = RecordingActivityAttributes(
  18. sessionID: sessionID,
  19. title: title,
  20. sourceName: sourceName
  21. )
  22. let state = makeState(elapsedSeconds: elapsedSeconds, isPaused: false)
  23. do {
  24. activity = try Activity.request(
  25. attributes: attributes,
  26. content: ActivityContent(state: state, staleDate: nil),
  27. pushType: nil
  28. )
  29. } catch {
  30. print("[RecordingLiveActivity] Failed to start: \(error.localizedDescription)")
  31. }
  32. }
  33. }
  34. func update(elapsedSeconds: TimeInterval, isPaused: Bool) {
  35. guard let activity else { return }
  36. let state = makeState(elapsedSeconds: elapsedSeconds, isPaused: isPaused)
  37. Task {
  38. await activity.update(ActivityContent(state: state, staleDate: nil))
  39. }
  40. }
  41. func end(elapsedSeconds: TimeInterval) {
  42. guard let activity else { return }
  43. self.activity = nil
  44. let finalState = makeState(elapsedSeconds: elapsedSeconds, isPaused: true)
  45. Task {
  46. await activity.end(
  47. ActivityContent(state: finalState, staleDate: nil),
  48. dismissalPolicy: .immediate
  49. )
  50. }
  51. }
  52. private func endExistingActivities() async {
  53. for existingActivity in Activity<RecordingActivityAttributes>.activities {
  54. await existingActivity.end(nil, dismissalPolicy: .immediate)
  55. }
  56. }
  57. private func makeState(
  58. elapsedSeconds: TimeInterval,
  59. isPaused: Bool
  60. ) -> RecordingActivityAttributes.ContentState {
  61. RecordingActivityAttributes.ContentState(
  62. timerStartDate: Date().addingTimeInterval(-elapsedSeconds),
  63. elapsedSeconds: elapsedSeconds,
  64. isPaused: isPaused
  65. )
  66. }
  67. }