experiment(PodcastPlayerView): handle AVAudioSession interruptions — pause on call, resume after
This commit is contained in:
@@ -56,6 +56,7 @@ final class PodcastPlayerViewModel {
|
|||||||
private var pollingTask: Task<Void, Never>?
|
private var pollingTask: Task<Void, Never>?
|
||||||
private var timeObserver: Any?
|
private var timeObserver: Any?
|
||||||
private var endObserver: Any?
|
private var endObserver: Any?
|
||||||
|
private var interruptionObserver: Any?
|
||||||
private var currentPodcastTitle: String = "Marks Podcast"
|
private var currentPodcastTitle: String = "Marks Podcast"
|
||||||
|
|
||||||
func start(articleUrl: String, articleTitle: String = "", claude: ClaudeService) {
|
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 = timeObserver { player?.removeTimeObserver(obs) }
|
||||||
if let obs = endObserver { NotificationCenter.default.removeObserver(obs) }
|
if let obs = endObserver { NotificationCenter.default.removeObserver(obs) }
|
||||||
endObserver = nil
|
endObserver = nil
|
||||||
|
if let obs = interruptionObserver { NotificationCenter.default.removeObserver(obs) }
|
||||||
|
interruptionObserver = nil
|
||||||
player = nil
|
player = nil
|
||||||
isPlaying = false
|
isPlaying = false
|
||||||
currentTime = 0
|
currentTime = 0
|
||||||
@@ -205,6 +208,28 @@ final class PodcastPlayerViewModel {
|
|||||||
self.updateNowPlaying()
|
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)
|
let interval = CMTime(seconds: 0.5, preferredTimescale: 600)
|
||||||
timeObserver = p.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] t in
|
timeObserver = p.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] t in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|||||||
Reference in New Issue
Block a user