diff --git a/Marks/Views/PodcastPlayerView.swift b/Marks/Views/PodcastPlayerView.swift index 52a02ec..303d5cb 100644 --- a/Marks/Views/PodcastPlayerView.swift +++ b/Marks/Views/PodcastPlayerView.swift @@ -56,6 +56,7 @@ final class PodcastPlayerViewModel { private var pollingTask: Task? private var timeObserver: Any? private var endObserver: Any? + private var interruptionObserver: Any? private var currentPodcastTitle: String = "Marks Podcast" func start(articleUrl: String, articleTitle: String = "", claude: ClaudeService) { @@ -120,6 +121,8 @@ final class PodcastPlayerViewModel { if let obs = timeObserver { player?.removeTimeObserver(obs) } if let obs = endObserver { NotificationCenter.default.removeObserver(obs) } endObserver = nil + if let obs = interruptionObserver { NotificationCenter.default.removeObserver(obs) } + interruptionObserver = nil player = nil isPlaying = false currentTime = 0 @@ -205,6 +208,28 @@ final class PodcastPlayerViewModel { self.updateNowPlaying() } + // Pause on phone calls / Siri; resume when interruption ends + interruptionObserver = NotificationCenter.default.addObserver( + forName: AVAudioSession.interruptionNotification, object: nil, queue: .main + ) { [weak self] notification in + guard let self, + let typeValue = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt, + let type = AVAudioSession.InterruptionType(rawValue: typeValue) else { return } + if type == .began { + self.player?.pause() + self.isPlaying = false + self.updateNowPlaying() + } else if type == .ended { + let optionsValue = notification.userInfo?[AVAudioSessionInterruptionOptionKey] as? UInt ?? 0 + let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue) + if options.contains(.shouldResume) { + self.player?.rate = self.playbackSpeed + self.isPlaying = true + self.updateNowPlaying() + } + } + } + let interval = CMTime(seconds: 0.5, preferredTimescale: 600) timeObserver = p.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] t in guard let self else { return }