The fun times building a tiny open source class to use an iOS device’s hardware volume buttons in 3rd party apps.
This wasn’t too hard, but the I thought the process merited a short blog post.
I recently made a pixel-for-pixel clone of Apple’s iOS 7
UIImagePickerController (the camera portion, not the library portion). The full code can be found on github.
My motivation for doing this was that I was working on a client app that included functionality to take a picture and analyze it to determine whether or not it passed certain quality checks (legibility, resolution, completeness, etc). I wanted to display a message based on the result of this quality check during the “review” process of
The part I want to discuss is the code that uses the phone’s hardware volume up button to snap a picture.
There are a few hurdles to jump over to make this seamless:
- There’s no official API or notification to observe the audio volume or hardware volume button presses
UIImagePickerControllerdoesn’t pass-through volume button presses to the system audio
- There’s no official way to stop the system audio from being modified on a volume button press
- The only way to disable the HUD that appears on volume change is to display an
MPVolumeView(it won’t work if it’s hidden or if its alpha is zero)
- The only way to set the system audio level is to use a deprecated method (i.e. if we want to undo a volume change caused by a volume button press)
- The system audio volume won’t go up if it’s already set to 1 and won’t go down if it’s set to 0. This means that button presses won’t be registered if audio is at its maximum or its minimum.
So I wrote a class called
JPSVolumeButtonHandler that solves the previous problems in the following way:
- Create an off-screen
- If the volume is at 1, set it to
0.99999f, if it’s at 0, set it to
0.00001f, otherwise do nothing
- KVO observe the
outputVolumeproperty of an
- Set the
AVAudioSession’s category to
AVAudioSessionCategoryAmbientto not duck any other volume
- Trigger up/down code blocks when KVO notifies us of a change
- Reset the system audio to its initial value when KVO notifies us that it has changed
- Discard KVO notifications when the new volume value is the same as our initial value, since that means we reset the volume
Thanks for reading!