前書き
今まで非公開の通知を利用したり、音量を監視して行っていた音量ボタンでの写真撮影ですが、iOS17.2からついにこのためのAPI「AVCaptureEventInteraction」が追加されました!
AVCaptureEventInteraction
今の所、日本語で書かれた情報が無かったので備忘録も兼ねて公開します。
始めて技術系の記事を書くので、至らない点もあるかと思いますがよろしくお願いします。
実装
実装方法ですが、公式のドキュメントに書いてある通り下記の記述で簡単に実装出来ます。
ただしAVCaptureの名前がついている通り、このAPIはUIImagePickerControllerのカメラやAVFoundationで制作したカスタムカメラの画面でのみ利用できます。
それ以外の画面ではAVCaptureEventInteractionはイベントを受信しません。
// Create a new capture event interaction with a handler that captures a photo.
let interaction = AVCaptureEventInteraction { [weak self] event in
// Capture a photo on "press up" of a hardware button.
if event.phase == .ended {
self?.camera.capturePhoto()
}
}
// Add the interaction to the view controller's view.
view.addInteraction(interaction)
eventInteraction = interaction
event.phase にはキャプチャ イベントの現在のフェーズが格納されます。
phase | 概要 |
---|---|
began | 音量ボタンを押した時のフェーズ |
ended | 音量ボタンを離した時のフェーズ |
cancelled | キャンセルした時のフェーズ |
このphaseにあわせて撮影の処理を記述していきます。例えば、音量ボタンを一度押すと撮影が一回実行されるようにしたい場合は 「ended」 のタイミングで処理を実行したり、連写を実装したい場合は 「began」 のタイミングで連写処理の開始を実装して 「ended」 で連写を終了する、といった感じでしょうか。
一時的にこの処理を止めたい場合は isEnabled をfalseに、完全に削除したい場合はviewからremoveInteraction します。
余談
ちなみに、このAPIが実装されたせいかiOS17.2から _UIApplicationVolumeUpButtonDownNotification といった非公開の音量ボタン通知は利用できなくなりました。
あんまり居ないかもしれませんが、もしも利用されている場合はiOS17.2以降はAVCaptureEventInteractionで処理するように修正することをオススメします。
後書き
iOS17.2以上とは言え、これで非公開のAPIをリジェクトの恐怖に怯えながら利用したり、outputVolumeを監視する必要も無くなりますね…実装も簡単ですし、カメラアプリ制作者にはとても助かるAPIです。
これからカメラアプリ制作する予定で音量ボタンをシャッターボタンにしたい方は、こちらのAPIを利用した方が絶対に良いです。outputVolumeを監視する手法と違って音量も変化しないですし。