0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Swift】AVCaptureSession 公式ドキュメントのコードをコンパイルできるよう修正してみた

Last updated at Posted at 2024-10-26

はじめに

本記事では、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にそのままコピペすると、コンパイルエラーが起きます。
きっと、公式ドキュメントでは簡略化された形でコードが記載されているのでしょう。


エラー画面
スクリーンショット 2024-10-26 14.18.35.png

エラーの解決方法

解決すべきコンパイルエラーは以下の2つです。

  1. Cannot find 'AVCaptureSession' in scope
  2. 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が必ずメインスレッドで動作するよう制限しているのです。

おわりに

説明は以上となります。
読んでいただき、ありがとうございました。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?