AVAudioSession.requestRecordPermission(_:)がDeprecatedなので対応しておく

## はじめに

マイクへのアクセス許可を求める処理として、 `AVAudioSession.requestRecordPermission(_:)` を利用していたのですが、[ドキュメント](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616601-requestrecordpermission)を読むと **Deprecated**となっておりiOS17までの利用となっているので対応しておくことにしました。

> **Deprecated**
Use [requestRecordPermission(completionHandler:)](https://developer.apple.com/documentation/avfaudio/avaudioapplication/4144305-requestrecordpermission) on AVAudioApplication instead.

https://developer.apple.com/documentation/avfaudio/avaudioapplication/4144305-requestrecordpermission

と記載してありますが、iOS17+Beta対象なので少し対応しづらいところがあります。
また個人的にはWebRTCを利用しているところもあり、 `AVAudioSession` ではなく `RTCAudioSession` を利用したいのですが、 `RTCAudioSession` には `requestRecordPermission(_:)` のようなAPIが用意されてなさそうだったので、別方法での対応を取ることにしました。

## これまでの`AVAudioSession.requestRecordPermission(_:)` での対応

`AVAudioSession.requestRecordPermission(_:)`　を利用していたコードはシンプルで、音声周りの管理クラスに以下のようなメソッドを用意して利用していました。

```Swift
private let session = AVAudioSession.sharedInstance()

func requestRecordPermission(completion: @escaping (Bool) -> Void) {
    session.requestRecordPermission { granted in
        completion(granted)
    }
}
```

## 一応 `AVAudioApplication.requestRecordPermission(completionHandler:)` への置き換えも

[AVAudioApplication.requestRecordPermission(completionHandler:)](https://developer.apple.com/documentation/avfaudio/avaudioapplication/4144305-requestrecordpermission)を代用するようにとドキュメントにも記載があったので、一応その対応も載せておきます。

```Swift
func requestRecordPermission() {
    AVAudioApplication.requestRecordPermission { granted in
        completion(granted)
    }
}
```
というように、 `AVAudioSession.requestRecordPermission(_:)` と同じように完了ハンドラで同期的にも書けるし、
`class func requestRecordPermission() async -> Bool` のような非同期メソッドとしても利用できます。
[ドキュメント](https://developer.apple.com/documentation/avfaudio/avaudioapplication/4144305-requestrecordpermission)のまま載せておきます。

```Swift
// Request permission to record.
if await AVAudioApplication.requestRecordPermission() {
    // The user grants access. Present recording interface.
} else {
    // The user denies access. Present a message that indicates
    // that they can change their permission settings in the
    // Privacy & Security section of the Settings app.
}
```

## `AVCaptureDevice.requestAccess(for:completionHandler:)` を利用する

はじめに記載しましたが、現状だとiOS17への対応がしづらいのと、個人的にはそもそも `AVAudioSession` ではなく `RTCAudioSession` を利用したいことから、 [AVCaptureDevice.requestAccess(for:completionHandler:)](https://developer.apple.com/documentation/avfoundation/avcapturedevice/1624584-requestaccess) で代用しました。

こちらはiOS17以降でも問題ない予定ですし、completionHandlerで同期的に、 `class func requestAccess(for mediaType: AVMediaType) async -> Bool` のような非同期的にも利用できます。
以下のように等価で代用できました。

```Swift
func requestRecordPermission(completion: @escaping (Bool) -> Void) {
    AVCaptureDevice.requestAccess(for: .audio) { granted in
        completion(granted)
    }
}
```

`for mediaType`には [AVMediaType](https://developer.apple.com/documentation/avfoundation/avmediatype)を指定しますが、 `.audio`を指定すれば、 `AVAudioSession.requestRecordPermission(_:)` を呼び出すことと同じであることも記載されていました。(安心です)

> **Note**
Calling this method with a media type of audio is equivalent to calling the requestRecordPermission(_:) method on AVAudioSession.

https://developer.apple.com/documentation/avfoundation/avcapturedevice/1624584-requestaccess

念の為、実際の動作的にも、マイクへのアクセス許可をしている場合は、システムがアラートを出さないように制御されることを確認できました。

## 終わりに

現状だと、同じようにDeprecatedに対応したいとなれば、ミニマムに修正できる `AVCaptureDevice.requestAccess(for:completionHandler:)` を利用する形で良いのではと思います。
また言うまでもないと思いますが、もし新規にマイクを使用する機能を入れる場合は、 `Info.plist` に `NSMicrophoneUsageDescription` キーとそれに対応する文字列を記述するのを忘れないようにしてください。アプリがデバイスのマイクにアクセスしようとした際にクラッシュしてしまうので、、

## 参考文献

この記事は、以下の情報を参考に書きました。

https://developer.apple.com/documentation/avfaudio/avaudiosession/1616601-requestrecordpermission

https://developer.apple.com/documentation/avfaudio/avaudioapplication/4144305-requestrecordpermission

https://developer.apple.com/documentation/avfoundation/avcapturedevice/1624584-requestaccess