【Swift/PhotoKit】PHAssetとは?モデルオブジェクトの取得と操作方法!

この記事からわかること
- PhotoKitとは?
- モデルオブジェクトの取得と操作方法
- PHPhotoLibraryクラスとは?
- PHAssetの使い方
- アセットを取得(フェッチ)する方法
- PHFetchResultクラスからオブジェクトを取り出す
enumerateObjects
メソッドの使い方 - 画像(
UIImage
)を取得する方法
index
[open]
\ アプリをリリースしました /
環境
- Xcode:15.0.1
- iOS:17.1
- Swift:5.9
- macOS:Sonoma 14.1
参考文献:Apple-PhotoKit
参考文献:Fetching Objects and Requesting Changes
PhotoKitとは?
そもそもPhotoKitとはApple製のデバイスに入っている「写真アプリ」で管理されている写真や動画を操作するためのAPIを提供している技術です。実際の中身はPhotos FrameworkとPhotosUI Frameworkの2つのフレームワークに分けられて構成されており、それぞれをimportすることで使用できるようになります。
Photos
カメラロール(フォトライブラリ)を管理するオブジェクトを提供するPHPhotoLibrary
や、実際の画像や動画などのアセットを管理するPHAsset
、アセットのコレクション(アルバムなど)を表現するPHAssetCollection
などといった基本的な写真アプリ操作機能を提供。
PhotosUI
画像のピッカービューを構築するためのPHPickerViewController
やその構成を定義するPHPickerConfiguration
などUIに関する機能を提供。
またPhotosUI
の中にPhotos
が含まれているためPhotosUI
のみでPhotos
の機能も使用できるようになります。
今回はPHAssetなどのモデルオブジェクトに焦点を当ててまとめていきます。
モデルオブジェクト
PhotoKitではフォトライブラリ内のデータを操作するためのAPIとしてモデルオブジェクトが複数用意されています。写真アプリ内のデータ構造をモデルオブジェクトにコピーして操作していくイメージです。
- PHAsset:画像、動画、Live Photos
- PHAssetCollection:アルバム or モーメント
- PHCollectionList:アルバムフォルダー or モーメントクラスター
上記のようにPhotoKitでは写真アプリ内の画像や動画などはPHAssetオブジェクトとして、アルバムはPHAssetCollectionオブジェクトとして操作できるようになっています。
またこれらのインスタンスは読み取り専用のimmutable(不変)で、メタデータのみを含み、モデルオブジェクトに対してクエリを構築し情報をフェッチします。
オブジェクトを変更したい場合は変更要求オブジェクト(performChangesメソッド)を構築して、明示的に共有オブジェクト(PHPhotoLibrary)にコミットする必要があります。
おすすめ記事:【Swift/PhotoKit】デバイスに写真を保存・削除・更新する方法!
PHPhotoLibraryクラス
PHPhotoLibrary
クラスはユーザーの写真ライブラリへのアクセスと変更を管理するオブジェクトです。shared
メソッドから共有されるシングルトンのインスタンスを参照します。
参照はシングルトンのインスタンスから
役割
- 写真アプリへのアクセス許可をユーザーに申請する
- アセットとコレクションに変更する
- ライブラリの更新を検知する
- 更新メッセージの登録
PHAssetクラス
PHAssetクラスはフォトライブラリ内の画像や動画、Live Photoなどのモデルオブジェクトでした。保持しているプロパティは以下の通りです。
このPHAssetを取得する方法を見ていきます。
アセットを取得(フェッチ)する方法
アセットを取得(フェッチ)するにはPHAssetの持つfetchAssets
メソッドを使用します。同名の引数違いで様々なメソッドが定義されていますが返り値がPHFetchResult<PHAsset>
型になるのは共通です。
例えば指定したメディアタイプ(画像や動画など)のみのアセットを取得する場合は以下のようになります。
アセットコレクション内のアセットを取得
識別子にマッチするアセットを取得
またフェッチにはPHFetchOptions型のオプションを渡すことができ順序のソートやフェッチする最大数を指定できます。
PHFetchResultクラス
PHFetchResultクラスはフェッチ結果を提供するクラスです。配列の要素にフェッチしたPHAsset、PHCollection,、PHAssetCollection、PHCollectionListのいずれかのオブジェクトを保持します。
保持する個数に参照できるcount
プロパティや存在するかどうかをチェックするcontains
メソッド、最初のオブジェクトを参照するfirstObject
プロパティなどが用意されています。
今回は保持しているオブジェクトを全てに特定のクロージャを実行できるenumerateObjects
を使用します。
クロージャーの中では対象のオブジェクト、インデックス、取り出しを停止させるBool値の3つの引数を取得できます。
画像(UIImage)を取得する方法
ここで一度PHAssetを使ってフォトライブラリの画像を取得しビューとして表示させる流れをみていきます。
- info.plistにキーを追加
- UIの構築
- PHAssetのフェッチ
- 画像(UIImage)の取得
info.plistにキーを追加
PhotoKitを使用してアセットやコレクションの取得、ライブラリの更新など、アプリがPhotoKitの高度な機能を使用するためにはアプリ内からデバイスの写真アプリにアクセスできるように「info.plist」に「NSPhotoLibraryUsageDescription」キーを追加する必要があります。

UIの構築
続いて必要となるUIを準備します。ViewController
クラスには表示用のUIImageView
とフォトライブラリのアセットを保持する用のプロパティを定義しておきます。またアセットを取得してセットするボタンと実際にビューに反映させるボタンも配置しておきます。
PHAssetのフェッチ
まずは現在のフォトライブラリをPhotoKitで操作できる形(アセット)になるようにPHAsset.fetchAssets
メソッドを使ってフェッチします。今回はオプションは指定なしにしておきました。またこのメソッドを呼び出した際に許可申請アラートが表示されます。取得できるのはPHFetchResult
型のデータです。
取得したPHFetchResultからをenumerateObjects
メソッドを使用してphotoAssets
プロパティに1つずつオブジェクト(PHAsset)を格納していきます。
画像(UIImage)の取得
PHAssetが取得できればPHImageManager
を使用してUIImageを取得するだけです。PHImageManager
の使用方法やリクエストオプションの概要は以下の記事を参考にしてください。
おすすめ記事:【Swift/PhotoKit】PHImageManagerの使い方!アセット操作と画像の取得
カメラロールから取得した画像のメタデータを取得する方法
PHPickerViewController
を使用してアルバムから写真を取得している場合に写真のメタデータ(撮影日時や撮影地など)を取得するにはいくつか注意点がありました。詳細は以下の記事を参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。