酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

UIImagePickerControllerを使って動画を録画しようとすると __TCCAccessRequest_block_invoke でクラッシュしてしまう

プロフィール画像などの静止画の撮影にUIImagePickerControllerを使うことはよくあり、UIImagePickerControllerを使って動画の録画ができることも知っていた。iOSアプリ開発に携わって11年ちょっと経つが、いままでUIImagePickerControllerを使って動画録画したことがなかった。

簡単に実装できると思っていたので下記のコードを書いた。

let vc = UIImagePickerController()
vc.delegate = self
vc.sourceType = .camera
vc.mediaTypes = [ "public.movie" ]
self?.present(vc, animated: true, completion: nil)

しかし、iOS 15.2の実機でこのコードを実行したところ、UIImagePickerControllerへの遷移時に謎のクラッシュが発生してしまった。スタックトレースが吐かれずに __TCCAccessRequest_block_invoke とだけ表示されている。

予期せぬTCCAccessRequest エラーに注意」によれば、以下のように記述があった。

カメラの使用、フォトライブラリの参照などを行う場合、info.plistに説明文の記述が必要。

  • カメラ : NSCameraUsageDescription
  • フォトライブラリ : NSPhotoLibraryUsageDescription

前述の通りプロフィール画像の撮影のために Info.plist にはすでに定義を追加済みである。他にもアプリ内で利用するためにPrivacy - Location When In Use Usage Description などの定義もすでに追加している。

f:id:ch3cooh393:20220111155554p:plain

まともなログが出ていないため原因がわからず、2時間ほど国内QAサイトやStack Overflowなどを検索してまわったがやはり原因がわからなかった。

ふと静止画撮影と動画録画の違いを考えたところ「音声の有無」に気付いた。結局これが当たりだったようで、クラッシュすることなく動画の録画画面に遷移できるようになった。

マイク使用の許可の定義 Privacy - Microphone Usage Description が足りていないのが原因だったようだ。