"Observe audio session notifications to ensure that your app responds appropriately to interruptions."
앱이 인터럽션에 대해 적합하게 응답하는 것을 보장하기 위해서 오디오 세션 노티피케이션을 탐색합니다.
iOS 및 watchOS 사용자 경험에서 인터럽션은 흔히 볼 수 있는 것들입니다. 예를 들어 아이폰에서 TV 앱을 통해 영상을 보고 있는 동안 전화 통화를 받는 시나리오를 생각해볼 수 있습니다. 이 경우 영상의 오디오는 페이드 아웃되고 재생은 일시정지되며, 전화의 링톤 소리가 페이드 인됩니다. 전화를 거절하면 TV 앱으로 되돌아가기 위해 컨트롤하고 영상의 오디오기 페이드인되면서 재생을 다시 시작합니다.
이와 같은 동작의 중심은 앱의 오디오 세션입니다. 인터럽션이 시작하거나 끝날 때 오디오 세션은 모든 등록된 옵저버에게 알려줍니다. 그렇기 때문에 옵저버는 적합한 액션을 취할 수 있게 됩니다. 예를 들어 AVPlayer는 앱의 오디오 세션을 모니터링하고, 인터럽션 이벤트에 대한 반응으로써 자동으로 재생을 일시정지하거나 재생합니다. 플레이어의 레이트 속성을 key-value observing으로 이와 같은 변화를 모니터링할 수 있으며, 플레이어가 재생을 일시정지하거나 재개할 때 필요한 경우 UI를 업데이트할 수도 있습니다.
대부분의 앱은 시스템의 기본값 인터럽션 동작에 의존합니다. 그러나 iOS 14.5를 시작으로 AVAudioSession
은 앱의 니즈를 더 잘 수용하기 위해 기본값 동작을 커스터마이징할 수 있는 방법을 제공합니다.
최근으 아이패드 모델은 사용자가 기기의 스마트 폴리오 커버를 닫을 때 하드웨어 수준에서 내장된 마이크를 음소거하는 기능을 제공합니다. 앱이 오디오를 재생하거나 녹음하면, 시스템이 마이크를 음소거할지라도 재생을 계속하길 원할 수 있습니다. 오디오 세션을 설정할 때 overrideMutedMicrophoneInterruption
옵션을 설정해서 기본값 인터럽션 동작을 비활성화할 수 있습니다.
전화 통화가 오는 것과 같은 시스템 알림은 활성화된 오디오 세션을 인터럽트합니다. 이와 같은 경우에서 앱의 오디오 세션이 시스템에 의해 인터럽트되지 않기를 선호한다면, setPrefersNoInterruptionsFromSystemAlerts(_:)
메소드에서 값을 설정해 이와 같은 설정을 나타내도록 할 수 있습니다.
AVAudioSession
을 포스트하는 인터럽션 노티피케이션을 직접적으로 탐색할 수 있습니다. 언제 시스템이 인터럽션 혹은 다른 이유(라우트 변경과 같은)에 기인해 시스템이 재생을 일시정지할지를 인식하길 원하는 경우 인터럽션 노티피케이션 탐색이 유용합니다. 오디오 인터럽션을 탐색하려면 interruptionNotification
타입의 노티피케이션을 탐색하기 위한 등록부터 시작해야 합니다.
func setupNotifications() {
// Get the default notification center instance.
let nc = NotificationCenter.default
nc.addObserver(self,
selector: #selector(handleInterruption),
name: AVAudioSession.interruptionNotification,
object: AVAudioSession.sharedInstance)
}
@objc func handleInterruption(notification: Notification) {
// To implement.
}
포스팅된 노티피케이션 객체는 인터럽션의 세부사항을 제공하는 채워진 사용자 정보 딕셔너리를 포함합니다. userInfo
딕셔너리로부터 AVAudioSession.InterruptionType
값을 가져와서 인터럽션의 타입을 결정할 수 있습니다. 인터럽션 타입은 인터럽션을 시작할지 혹은 끝날지를 나타냅니다.
@objc func handleInterruption(notification: Notification) {
guard let userInfo = notification.userInfo,
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
return
}
// Switch over the interruption type.
switch type {
case .began:
// An interruption began. Update the UI as necessary.
case .ended:
// An interruption ended. Resume playback, if appropriate.
guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
// An interruption ended. Resume playback.
} else {
// An interruption ended. Don't resume playback.
}
default: ()
}
}
인터럽션 타입이 AVAudioSession.InterruptionType.ended
인 경우 userInfo
딕셔너리는 재생이 자동으로 재개될지를 결정하기 위해 사용하는 AVAudioSession.InterruptionOptions
값을 포함합니다.
앱이 변경사항 라우트에 적합하게 응답하는 것을 보장할 수 있도록 오디오 세션 노티피케이션을 탐색합니다.
https://developer.apple.com/documentation/avfaudio/avaudiosession/responding_to_audio_session_route_changes
https://velog.io/@panther222128/Responding-to-Audio-Session-Route-Changes