Siri Shortcuts(App Intents)の対応が一段落し、次はユーザーが記録に写真を添付できるようにするため、写真ライブラリからの画像選択機能を実装しました。
1. 古い記事の情報に従って権限リクエストを書いてしまった
検索して最初に見つけた記事の多くがUIImagePickerController時代のもので、「写真ライブラリへのアクセス許可を明示的にリクエストするコード」がそのまま紹介されていました。
PHPhotoLibrary.requestAuthorization { status in
// 権限チェック
}
このコードをそのまま実装したところ、動作はするものの権限ダイアログの出るタイミングに違和感がありました。調べてみると、新しいPHPickerViewControllerはシステムの写真アプリ内でユーザーが選んだ写真だけをアプリに渡す仕組みになっており、アプリ側からライブラリ全体へのアクセス権限を要求する必要がないケースがほとんどだと分かりました。用途によっては上記の権限リクエスト自体が不要でした。
2. Info.plistの権限説明文が不要なのに書いてしまっていた
前項の勘違いを引きずったまま、Info.plistにNSPhotoLibraryUsageDescription(写真ライブラリへのアクセス許可の説明文)を追加していました。
PHPickerViewControllerだけを使う場合、
NSPhotoLibraryUsageDescriptionの追加は不要
PHPickerViewController単体で完結する実装であれば、この説明文自体が不要でした。逆に、選択後の写真をアプリ独自のアルバム機能で保存・編集するなど、ライブラリへの書き込みや全体アクセスが必要になった時点で初めて権限説明文が必要になります。今の実装で本当に必要な権限なのかを毎回確認するようになりました。
3. 選択した画像がすぐに使えず戸惑った
ピッカーで写真を選んだ直後、UIImageとしてすぐに扱えるものだと思い込んでいたのですが、実際にはNSItemProvider経由で非同期に読み込む必要がありました。
読み込みが完了する前に画面を更新しようとして、一瞬空白の画像が表示される不具合が発生しました。読み込み中はローディング表示を出し、完了後に画像をセットするよう処理を分けたところ解決しました。同期的に画像が手に入ると思い込んでいたのが原因でした。
4. 複数枚選択時の順序が保証されないと知らなかった
複数枚の写真をまとめて選べるようにしたところ、選んだ順番とアプリ内での表示順がずれてしまうことがありました。
NSItemProviderの読み込みはそれぞれ非同期に走るため、読み込みが完了した順に配列へ追加すると、選択した順序と一致しなくなります。選択結果(PHPickerResultの配列)のインデックスを保持しておき、読み込み完了後にそのインデックス順で並べ直す処理を追加して解決しました。
まとめ
PHPickerViewControllerはシステム側で選択が完結するため、多くの場合ライブラリ全体への権限リクエストが不要- 権限説明文(
NSPhotoLibraryUsageDescription)も、用途によっては追加不要。今の実装に本当に必要か都度確認する - 選択した画像は
NSItemProvider経由の非同期読み込みになるため、同期的に使えると思い込まない - 複数枚選択時は、読み込み完了順ではなく元のインデックス順で並べ直す必要がある
「写真選択くらい簡単だろう」と思っていましたが、新しいAPIならではの非同期処理・権限まわりの仕様変更に何度もつまずきました。
次は、App Groupsでウィジェットとデータを共有してみた話をまとめます。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント