0

The approved KVO approach for responding to device volume level changes stops detecting volume button presses after min/max outputVolume is reached. I'd like to continue to receive those button press events after min/max, so I assume I need to try this solution, even if it's not supported by Apple. However, I'm very much an amateur iOS programmer so I could use a hint. Here's what I've been doing (using RxSwift):

NotificationCenter.default.rx.notification(Notification.Name(rawValue: "AVSystemController_AudioVolumeNotificationParameter"))
                .subscribe(onNext: { [weak self] notification in
                    guard let my = self else { return }
                    my.volumeNotification.accept(notification.userInfo!["AVSystemController_AudioVolumeNotificationParameter"] as! Double)
                })
                .disposed(by: disposeBag)

Should I instead be subscribing to a Notification named "MPVolumeControllerDataSource_SystemVolumeDidChange"?

Thanks in advance!

1 Answers1

-1

Three cheers for open source, specifically: JPSVolumeButtonHandler. This component works like a champ, and uses the Apple-approved KVO technique. Be aware that this component sets AVAudioSession options to .mixWithOthers which prevents MPRemoteCommandCenter from receiving/handing any BlueTooth commands. So if you need BT (Swift 5):

let volumeButtonHandler = JPSVolumeButtonHandler(up: {
    // handle up press
}, downBlock: {
    // handle down press
})
volumeButtonHandler.sessionOptions = [] // allow remote BT

I also found that programmatically setting the device volume to 0.5 before initializing the button handler avoided occasional min/max barriers. If the device initial volume was close to the min or max, the handler would stop after a few button presses:

try AVAudioSession.sharedInstance().setActive(true, options: [])
MPVolumeView(frame: .zero).volumeSlider.value = 0.5