일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 스위프트 앨범
- Flutter UIKitView MethodChannel
- 안드로이드 바로가기
- flutter rotate
- 스위프트 푸시
- 스위프트 테이블 뷰 셀
- 푸시 데이터 저장
- 안드로이드 앨범
- 스위프트
- swift sms
- Flutter NativeView
- 플러터 뷰 컨트롤러
- Swift flutterview
- NotificationService Extension
- 스위프트 UserDefaults
- Swift flutterviewcontroller
- silent push
- swift 문자
- 스위프트 카메라
- 안드로이드 숏컷
- native flutter view
- 안드로이드 에러
- 앱 꺼졌을 때 푸시 데이터 저장
- 안드로이드 FCM
- 앱 백그라운드 푸시 데이터 저장
- 스위프트 웹뷰
- flutter 회전
- swift autolayout
- 노티피케이션 익스텐션
- FlutterView MethodChannel
- Today
- Total
Things take time
[SWIFT] 오디오 감지를 위한 옵저버 AVSystemController_SystemVolumeDidChangeNotification 사용 불가(iOS15) 본문
[SWIFT] 오디오 감지를 위한 옵저버 AVSystemController_SystemVolumeDidChangeNotification 사용 불가(iOS15)
겸손할 겸 2021. 7. 5. 14:36[용도]
사용자가 직접 하드웨어 볼륨키를 이용하여 사운드를 변경했을 때를 감지하기 위한 방법으로 아래와 같은 코드를 사용했다.
NotificationCenter.default.addObserver(self, selector: #selector(volumeChanged), name: NSNotification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification"), object: nil)
그런데 iOS15 베타버전을 설치하여 이것저것 테스트 해보는 도중, 위의 코드가 되지 않는 문제가 발생했다. 15미만은 정상 작동함.
기본적으로 위에서 사용하는 코드는, AVSystemController_SystemVolumeDidChangeNotification 이란 문자열 값을 사용하여, 직접 사용하고 있는 것인데 이 값은 iOS 버전이 올라가면 값이 바뀔 수 있다. 이유는 애플에서 직접 제공하는 Property값이 아닌 값이기에 지원하지 않아도 이상하지 않은 것이다.
그러므로 직접 애플에서 고시한 property를 사용하는 것이 올바른 방법이겠다.
[코드]
AVFoundation을 import하고,
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setActive(true)
} catch {
print("[Gyeom] Error occured :: \(error)")
}
audioSession.addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil)
위와 같은 오디오 세션에 직접 옵저버를 할당한다. forKeyPath에 들어가는 outputVolume값은 아래 링크에서 확인할 수 있다.
https://developer.apple.com/documentation/avfaudio/avaudiosession/1616533-outputvolume
문서를 읽다보면, key-value observing을 통해 해당 값에 대한 감지가 가능하다고 하는데 이를 줄여 KVO방식이라 한다.
많이 들어봤을 수 있겠지만, RxSwift와 같은 종류의 개발 문법(?)라이브러리가 이런 방식으로 코딩하는 것으로 알고 있다.(Rx공부해야하는데.. SwiftUI + Combine도..)
특정 변수나, 값에 대한 변화를 감지하여 해당 값 변화가 이루어 졌을 때 UI를 업데이트 한다던지에 대한 코드를 작성해서 재사용성을 줄이는 것으로 알고있는데 뭐 그런 방식으로 해당 프러퍼티의 값을 미리 하는 것이다.
그리고 아래의 함수를 오버라이드한다.
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("[Gyeom]observeValue call")
let audioSession = AVAudioSession.sharedInstance()
if keyPath == "outputVolume"{
let volume = audioSession.outputVolume
print("[Gyeom] volume : \(audioSession.outputVolume)")
}
}
옵저버로 등록한 것이 있다면, 위의 함수가 호출되는데 이 때 keyPath가 위에 등록한 outputVolume이라면, 기존의 작업을 수행하면 되는 것이다. 사용자가 설정한 값은 AudioSession.sharedInstance().outputVolume으로 얻어 낼 수 있다.
[출처]
https://stackoverflow.com/questions/68249775/in-ios15-system-volume-change-observer-not-working
내가 올림 ㅋ
추가 => 2021/10/22
위의 내용대로 화면은 정상적으로 구현되나, 화면 뷰 컨트롤러가 여러개인 경우 해당 옵저버가 등록된후 제거해주지 않으면 안된다.
AudioSession.sharedInstance().removeObserver를 등록해주면되고, 현재 나는 아래의 함수로 변경해서 사용중이다.
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setActive(true)
} catch {
print("[Gyeom] Error occured :: \(error)")
}
// NSKeyValueObservation
self.volumeChangeObservation = audioSession.observe(\.outputVolume, changeHandler: {
(av, _) -> Void in
let volume = av.outputVolume
if volume > 0 {
}else {
}
})
// audioSession.addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil)
그리고 화면이 종료되거나 메모리 할당 될 때
self.volumeChangeObservation = nil
'iOS (기능)' 카테고리의 다른 글
[SWIFT] URL형식으로 된 String에서 Parameter 추출 (0) | 2021.11.19 |
---|---|
[SWIFT] Https 인증서 관련 우회 방법(Webview, API(Http통신/Alamofire) (0) | 2021.07.30 |
[SWIFT] CornerRadius 상단, 하단 특정 위치에만 주기 (0) | 2021.06.23 |
[iOS] 라이브러리 현재 버전 값 얻기 및 특정 버전 사용 방법 (0) | 2021.06.21 |
[SWIFT] 시스템 버전 값 비교(String Float Compare) (0) | 2021.05.25 |