Skip to content

Instantly share code, notes, and snippets.

@AmitaiB
Created August 13, 2021 02:52
Show Gist options
  • Save AmitaiB/e302de8266458f08aba7f33204cec622 to your computer and use it in GitHub Desktop.
Save AmitaiB/e302de8266458f08aba7f33204cec622 to your computer and use it in GitHub Desktop.
Modified Audio Interruption Monitor with delegate pattern
//
// 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