🔒

【iOS 18】ロック画面からカメラ機能へアクセスする

2024/06/30に公開

iOSにプリインストールされているカメラアプリは、ロック画面の状態であっても、コントロールをロングタップすることでカメラ機能へアクセスできます。iOS 18からは同様の機能がサードパーティ製アプリで実装できるようになりました。
本記事では、ロック画面の状態からカメラ機能へアクセスする方法について解説します。

https://developer.apple.com/jp/videos/play/wwdc2024/10204/

LockedCameraCapture

LockedCameraCaptureは、iOS 18から使用可能なフレームワークです。LockedCameraCaptureフレームワークには、ロック画面からカメラ機能へアクセスするためのAPIが定義されています。

Locked Camera Capture Extensionの追加

Locked Camera Capture Extensionは、ロック画面からカメラ機能へアクセスする機能を作成するためのテンプレートファイルです。以下の手順に従って、Locked Camera Capture ExtensionをアプリのXcodeプロジェクトに追加します。

  1. Locked Camera Capture Extensionを追加したいアプリのXcodeプロジェクトを開き、[File] > [New] > [Target]の順に選択します。

  2. 「Capture Extension」のテンプレート、[Next]を選択します。

  3. Product Name項目にターゲット名を入力し、[Finish]を選択します。

  4. 手順3でProduct Name項目に入力した名称のフォルダがナビゲーター領域に表示されていれば、Locked Camera Capture Extensionの追加は完了です。

ファイル構成

Locked Camera Capture Extensionを追加すると、以下の2つのswiftファイルが自動的に追加されます。

各ファイルの概要

  • LockedCapture.swift
    Locked Camera Capture Extension内のプログラムのエントリポイントを定義しています。
  • LockedCaptureViewFinder.swift
    コントロールがロングタップされた時に表示するカメラ画面が定義されています。Locked Camera Capture ExtensionをXcodeプロジェクトに追加すると、UIViewControllerRepresentable プロトコルに準拠した、UIImagePickerController のカメラ画面を表示するLockedCaptureViewFinder がデフォルトで定義されています。

https://developer.apple.com/forums/thread/756842?answerId=791468022#791468022

Info.plistファイルの編集

ホストアプリとLocked Camera Capture ExtensionのInfo.plist の両方に、Privacy - Camera Usage Description を追加し、カメラを使用する理由を明記します。

CameraCaptureIntent プロトコル

CameraCaptureIntent プロトコルに準拠したApp Intentを新たに定義します。
CameraCaptureIntent プロトコルに準拠したApp Intentは、App Intent経由でカメラ機能へアクセスできます。

コントロールウィジェット経由でCameraCaptureIntent プロトコルに準拠したApp Intentを実行することで、コントロールがロングタップされた時に、カメラ機能へアクセスできるようになります。
コントロールがロングタップされると、CameraCaptureIntent プロトコルに準拠したApp Intentのperform() が実行されます。perform() が完了すると、Locked Camera Capture Extension内の@main 属性が付与されているLockedCameraCaptureExtension プロトコルに準拠したインスタンスが生成されます。

CameraCaptureIntent プロトコルに準拠するためにAppContext を定義します。AppContext はLocked Camera Capture Extensionとホストアプリ間で、共有したい値を保存する時に使用します。例えば、ホストアプリ側で設定した値を、AppContext 経由でLocked Camera Capture Extension側で取得することができます。

また、CameraCaptureIntent プロトコルに準拠したApp Intentのターゲットには、ホストアプリ、Locked Camera Capture Extension、(後ほど作成する)Widget Extensionの3つを指定します。

LockedCameraCaptureExtension プロトコル

LockedCameraCaptureExtension プロトコルは、Locked Camera Capture Extensionを生成するためのプロトコルです。LockedCameraCaptureExtension プロトコルに準拠した構造体は、LockedCameraCaptureUIScene インスタンスを返すbody プロパティを定義します。画面ロック状態から表示したいカメラ画面のViewを、LockedCameraCaptureUIScene のイニシャライザの引数に指定します。この時、イニシャライザ経由でLockedCameraCaptureSession インスタンスをViewに渡します。

LockedCameraCaptureSession は、Locked Camera Capture Extensionとホストアプリ間で、やりとりを行うためのAPIが定義されているクラスです。LockedCameraCaptureSession インスタンス経由で、Locked Camera Capture Extension側からホストアプリを呼び出したり、撮影したデータを格納するためのパスを取得することができます。

Widget Extensionの追加

ロック画面からCameraCaptureIntent プロトコルに準拠したApp Intentを実行するため、Widget ExtensionをアプリのXcodeプロジェクトに追加し、コントロールウィジェットを作成します。コントロールウィジェットの作成方法は以下の記事でまとめていますので、必要に応じてご参照ください。
https://zenn.dev/naoya_maeda/articles/b5e13101cdf904

コントロールウィジェットの定義

コントロールがロングタップされた時に、CameraCaptureIntent プロトコルに準拠したApp Intentを実行するコントロールウィジェットを定義します。

カメラへのアクセスリクエスト処理

ロック画面からカメラ機能へアクセスする前に、ユーザーからカメラへのアクセス許諾を得ておく必要があるため、ホストアプリ側でカメラへのアクセスをリクエストする処理を実行します。

https://developer.apple.com/forums/thread/756842?answerId=790760022#790760022

実行結果

本記事では、ロック画面からカメラ機能へアクセスする方法について解説しました。次回の記事では、ロック画面から起動したカメラで撮影した写真を、フォトライブラリに保存する方法を解説します。
https://zenn.dev/naoya_maeda/articles/251490c8101edd

参考資料

・Build a great Lock Screen camera capture experience
https://developer.apple.com/jp/videos/play/wwdc2024/10204/

Discussion