📷

iOS16でのマルチタスク環境下でのカメラ利用

2023/01/04に公開

iPad16系で搭載されたステージマネジャ環境下においてマルチタスク(PiP, Split View, Slide Over)状態でも気軽にカメラが利用できるようになりました。
次のようなコードを既存のコードに追加することで、マルチタスク状態でもカメラが利用可能です。

let session = AVCaptureSession()
// iPhoneで値を操作すると例外が発生するため、isMultitaskingCameraAccessSupportedで対応しているか確認します
if #available(iOS 16.0, *), session.isMultitaskingCameraAccessSupported {
  session.isMultitaskingCameraAccessEnabled = true
}

カメラ利用の割り込みが発生する場合があるのでハンドリングしてあげましょう。

NotificationCenter.default.addObserver(self, selector: #selector(sessionInterruptionEnded(_:)), name: .AVCaptureSessionInterruptionEnded, object: session)
NotificationCenter.default.addObserver(self, selector: #selector(sessionWasInterrupted(_:)), name: .AVCaptureSessionWasInterrupted, object: session)

@objc
private func sessionWasInterrupted(_ notification: Notification) {
  guard let userInfoValue = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as AnyObject?,
       let reasonIntegerValue = userInfoValue.integerValue,
       let reason = AVCaptureSession.InterruptionReason(rawValue: reasonIntegerValue),
       let session = notification.object as? AVCaptureSession else {
    return
}
  if reason == .videoDeviceInUseByAnotherClient {
 // カメラの制御が別のアプリに映ったときの処理
  } else if reason == .videoDeviceNotAvailableWithMultipleForegroundApps {
 // マルチタスク権限のないアプリで、他のアプリがフォアグラウンドになりカメラ利用できなくなったときの処理
 }
}

@objc
private func sessionInterruptionEnded(_ notification: Notification) {
  guard let userInfoValue = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as AnyObject?,
       let reasonIntegerValue = userInfoValue.integerValue,
       let reason = AVCaptureSession.InterruptionReason(rawValue: reasonIntegerValue),
       let session = notification.object as? AVCaptureSession else {
    return
  }
}

冒頭で気軽にと書いたのは、iOS13.5以降でもcom.apple.developer.avfoundation.multitasking-camera-accessの権利をAppleに申請すれば利用可能のようです。

Discussion