Override iOS volume buttons

Stack Overflow:

Warning Private API usage follows. We MUST have some special circumstances that may allow you to get through.

Take look at Explore the iOS SDK and use undocumented APIs from 2012.

To summarise, you need to call the private method - [UIApplication setWantsVolumeButtonEvents:YES] to enable the following notifications:

  • _UIApplicationVolumeUpButtonDownNotification
  • _UIApplicationVolumeUpButtonUpNotification
  • _UIApplicationVolumeDownButtonDownNotification
  • _UIApplicationVolumeDownButtonUpNotification

In Swift this can be enabled with something like:

@objc public protocol UIApplicationPrivate {
    @objc func setWantsVolumeButtonEvents(_:Bool)

class VolumeButtonsObserver {
    private static var observer: NSObjectProtocol?

    static func setup(with application: UIApplication) {
        observer = NotificationCenter.default.addObserver(forName: nil,
                                                          object: nil,
                                                          queue: nil,
                                                          using: handleEvent)

        let application = unsafeBitCast(application, to:UIApplicationPrivate.self)

    private static func handleEvent(_ notification: Notification) {
        switch notification.name.rawValue {
        case "_UIApplicationVolumeUpButtonDownNotification": print("Volume Up Button Down")
        case "_UIApplicationVolumeUpButtonUpNotification": print("Volume Up Button Up")
        case "_UIApplicationVolumeDownButtonDownNotification": print("Volume Down Button Down")
        case "_UIApplicationVolumeDownButtonUpNotification": print("Volume Down Button Up")
        default: break

UIApplicationPrivate via Silencing a warning for explicitly constructed selector.