Created
August 13, 2021 02:52
-
-
Save AmitaiB/e302de8266458f08aba7f33204cec622 to your computer and use it in GitHub Desktop.
Modified Audio Interruption Monitor with delegate pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AudioInterruptionMonitor.swift | |
// JWPlayerDemo | |
// | |
// Created by Amitai Blickstein | |
// Copyright © 2019. All rights reserved. | |
// | |
// Credit: Code modified from Mohamed Afifi -> | |
// https://github.com/quran/quran-ios/blob/master/QueuePlayer/AudioInterruptionMonitor.swift | |
import AVFoundation | |
// MARK: Usage | |
/* | |
extension SwiftViewController: AudioInterruptionMonitorDelegate { | |
func onAudioInterruption(type: AudioInterruptionType) { | |
switch type { | |
case .began: player?.pause() | |
case .endedShouldResume: player?.play() | |
case .endedShouldNotResume: player?.stop() | |
} | |
} | |
} | |
*/ | |
// MARK: Type Safety | |
enum AudioInterruptionType { | |
case began | |
case endedShouldResume | |
case endedShouldNotResume | |
} | |
protocol AudioInterruptionMonitorDelegate: AnyObject { | |
func onAudioInterruption(type: AudioInterruptionType) | |
} | |
class AudioInterruptionMonitor { | |
weak var delegate: AudioInterruptionMonitorDelegate? | |
init() { | |
NotificationCenter.default | |
.addObserver(self, | |
selector: #selector(onInterruption(_:)), | |
name: .audioInterruption, | |
object: nil) | |
} | |
deinit { | |
NotificationCenter.default | |
.removeObserver(self, | |
name: .audioInterruption, | |
object: nil) | |
} | |
@objc private func onInterruption(_ notification: Notification) { | |
guard let type = typeFrom(notification) else { return } | |
switch type { | |
case .began: | |
delegate?.onAudioInterruption(type: .began) | |
case .ended: | |
guard let playerShouldResume = optionsFrom(notification)?.contains(.shouldResume) | |
else { return } | |
let endedType: AudioInterruptionType = playerShouldResume ? | |
.endedShouldResume : .endedShouldNotResume | |
delegate?.onAudioInterruption(type: endedType) | |
@unknown default: | |
fatalError("'@unknown default' in switch, line \(#line).") | |
} | |
} | |
// MARK: Helpers | |
func typeFrom(_ notification: Notification) -> AVAudioSession.InterruptionType? { | |
guard | |
let info = notification.userInfo, | |
let rawType = info[AVAudioSessionInterruptionTypeKey] as? UInt | |
else { return nil } | |
return AVAudioSession.InterruptionType(rawValue: rawType) | |
} | |
func optionsFrom(_ notification: Notification) -> AVAudioSession.InterruptionOptions? { | |
guard | |
let info = notification.userInfo, | |
let rawOptions = info[AVAudioSessionInterruptionOptionKey] as? UInt | |
else { return nil } | |
return AVAudioSession.InterruptionOptions(rawValue: rawOptions) | |
} | |
} | |
// Makes the code above more readable | |
extension Notification.Name { | |
static var audioInterruption: Self { AVAudioSession.interruptionNotification } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment