Sponsor Link
環境&対象
- macOS Big Sur 11.3 beta
- Xcode 12.4
- iOS 14.4
PHPhotoLibrary
いわゆる “写真” アプリのデータへアクセスするためのフレームワークです。
UIImagePickerController
iOS14 以前では、UIImagePickerController を使用して、写真選択の UI を表示していました。
この UI を表示するためには、ユーザーから事前に許諾をもらう必要があり、そのための API が requestAuthorization でした。
以下のように使っていました。
if PHPhotoLibrary.authorizationStatus() != .authorized {
PHPhotoLibrary.requestAuthorization { status in
if status == .authorized {
// ok to access
} else if status == .denied {
// rejected....
}
}
}
以前に許諾されたことがないと以下のような UI が表示されました。(見たことある人多いと思います。)

# PhotoAlbum という名前のサンプルアプリで動かしたので、少し混乱するかもしれません。
PHPickerViewController
iOS14 以降は、ユーザーが明示的に許諾せずとも、必要なデータにだけアプリからもアクセスできるようにする PHPickerViewController が用意されました。
この PHPickerViewController を使う時には、ユーザーへの許諾リクエストは不要です。(内部的にも、Picker は別プロセスで動作し、ユーザーが選択したものだけをアプリに渡すようになっています。)
[SwiftUI] UIImagePickerController を SwiftUI から使う方法
PHPhotoLibrary.requestAuthorization
iOS13 まで
以前の PHPhotoLibrary.requestAuthorization には、引数は、completion closure だけでした。
Apple のドキュメントは、こちら。
ドキュメントを確認するとわかりますが、iOS 14.0 で deprecated になってます。
iOS14 以降
iOS14 以降では、引数違いで同名の API が用意されています。
Apple のドキュメントは、こちら。
例によって(?)、”No overview available.” なドキュメントですが、以前のものから使い方は大きくは変わっていないように見えます。
追加された引数で指定できるのは、以下のものです。
- PHAccessLevelAddOnly
- PHAccessLevelReadWrite
Info.plist に登録することが必要なキー “Privacy – Photo Library Usage Description” と ”Privacy – Photo Library Additions Usage Description” に対応づいているように見えます。
フォトライブラリを読み出すだけなのか、追加するのかの違いのようです。
確認していませんが、おそらく対応するキーが登録されていないとエラーになる気がします。
上記の引数は、iOS14 で追加された API に追加された引数ですが、completion closure(handler) に渡される値も少し変わっていました。
completion closure
iOS13 以前、iOS14 以降 いずれも、closure の定義は、以下のようになっています。
handler: @escaping (PHAuthorizationStatus) -> Void)
変更は、PHAuthorizationStatus の定義にありました。
PHAuthorizationStatus のとりえる値は以下のようになっています。
- .notDetermined : まだ確認していない状態
- .restricted : ユーザーが許諾する権限を持っていない状態
- .denied : 許可しなかった状態
- .authorized : 許可した状態
- .limited : 一部のみ許可した状態
最後の、.limited が、iOS14 になって追加されたものです。
新しいオプション .limited とは?
新しく追加された .limited オプションは、一部のみ許可した状態 です。
問題は、この 「一部」 が、過去に一度選択した写真 を意味していることです。(アプリごとに管理されていると思われます)
アプリで、再度写真を選択しようとしても、過去に選んだ写真しか選択できません。
この 過去に一度選択した写真 を変更するためには、以下の手順を必要とするようです。
- PHPhotoLibrary.shared().register() を使って、変更検知できるようにする (PHPhotoLibraryChnageObserver に準拠が必要)
- PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: ) を使用して、再度選択させる
- PHPhotoLibraryChnageObserver.photoLibraryDidChange が呼び出されるので、変更に応じて処理する
iOS14 で導入された PHPickerViewController を使うのであれば、上記の複雑な手順とは無縁です。
まとめ:PHPhotoLibrary.requestAuthorization の変更点@ iOS14
- PHPickerViewController を使うのであれば、requestAuthorization は不要になった
- requestAuthorization の結果として .limited という状態を取りえるようになった
- .limited の情報を変更するためには、PHPhotoLibraryChnageObserver というプロトコルと presentLimitedLibraryPicker を使用する必要がある
- .limited 状態は、ユーザー・開発者 双方に優しくないので PHPickerViewController を使うのが良い。ただし、多くの写真を選択させる時には、PHPickerViewController が理想の UI でない可能性が高いので、要検討。
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Sponsor Link