はじめに
本記事では、Swiftの公式ドキュメント(AVCaptureSession)記載のコードについて、
コンパイルできるよう修正する方法を解説します。
開発環境
OS : macOS Sequoia 15.0.1
Xcode : Version 16.0
修正前のコード
以下は公式ドキュメント(AVCaptureSession)に記載されているコードです。
// Create the capture session.
let captureSession = AVCaptureSession()
// Find the default audio device.
guard let audioDevice = AVCaptureDevice.default(for: .audio) else { return }
do {
// Wrap the audio device in a capture device input.
let audioInput = try AVCaptureDeviceInput(device: audioDevice)
// If the input can be added, add it to the session.
if captureSession.canAddInput(audioInput) {
captureSession.addInput(audioInput)
}
} catch {
// Configuration failed. Handle error.
}
上記のコードは、XCodeにそのままコピペすると、コンパイルエラーが起きます。
きっと、公式ドキュメントでは簡略化された形でコードが記載されているのでしょう。
エラーの解決方法
解決すべきコンパイルエラーは以下の2つです。
- Cannot find 'AVCaptureSession' in scope
- Return invalid outside of a func
Cannot find 'AVCaptureSession' in scope
このエラーはAVCaptureSession
がスコープから参照できないために起こっています。
コードの冒頭にimport AVCaptureSession
を追加することで解決できます。
Return invalid outside of a func
これは、guard文の else { return }
の箇所で起きているエラーです。
return
には「関数・メソッド・クロージャのスコープの外では使えない」といった制限があります。
guard文以下の式をまるごと関数の中に入れてあげると、このエラーを解決することができます。
修正後のコード
// Create the capture session.
+ import AVFoundation
let captureSession = AVCaptureSession()
+ @MainActor
+ func setupAudioInput(){
// Find the default audio device.
guard let audioDevice = AVCaptureDevice.default(for: .audio)
else { return }
do {
// Wrap the audio device in a capture device input.
let audioInput = try AVCaptureDeviceInput(device: audioDevice)
// If the input can be added, add it to the session.
if captureSession.canAddInput(audioInput) {
captureSession.addInput(audioInput)
}
} catch {
// Configuration failed. Handle error.
}
+ }
(備考) func setupAudioInput()
に @MainActor
をつけている理由
AVCaptureSession
のインスタンス( captureSession
)は、UIの更新に影響を与える要素であるため、メインスレッドで動作するように制限されています。
しかし、captureSession
を参照しているsetupAudioInput
は関数であり、どのスレッドでも実行できてしまいます。
setupAudioInput
がメインスレッド以外のスレッドで実行されると、参照されているcaptureSession
もメインスレッドの外で実行されてしまうことになります。
そうすると、captureSession
が安全に参照されているか、コンパイルでは確認できません。
そこで、setupAudioに@MainActor
をつけて、setupAudioが必ずメインスレッドで動作するよう制限しているのです。
おわりに
説明は以上となります。
読んでいただき、ありがとうございました。