[iOS] PHPhotoLibrary.requestAuthorization(_:) に入った変更 @iOS14

PHPhotoLibrary へのアクセスリクエストするための API(requestAuthorization) が変更されていたので、メモ。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.3 beta
  • Xcode 12.4
  • iOS 14.4

PHPhotoLibrary

いわゆる "写真” アプリのデータへアクセスするためのフレームワークです。

UIImagePickerController

iOS14 以前では、UIImagePickerController を使用して、写真選択の UI を表示していました。

この UI を表示するためには、ユーザーから事前に許諾をもらう必要があり、そのための API が requestAuthorization でした。

以下のように使っていました。

PHPhotoLibrary.requestAuthorization 例

        if PHPhotoLibrary.authorizationStatus() != .authorized {
            PHPhotoLibrary.requestAuthorization { status in
                if status == .authorized {
                    // ok to access
                } else if status == .denied {
                    // rejected....
                }
            }
        }

以前に許諾されたことがないと以下のような UI が表示されました。(見たことある人多いと思います。)

AuthorizationScreen
AuthorizationScreen

# PhotoAlbum という名前のサンプルアプリで動かしたので、少し混乱するかもしれません。

PHPickerViewController

iOS14 以降は、ユーザーが明示的に許諾せずとも、必要なデータにだけアプリからもアクセスできるようにする PHPickerViewController が用意されました。

この PHPickerViewController を使う時には、ユーザーへの許諾リクエストは不要です。(内部的にも、Picker は別プロセスで動作し、ユーザーが選択したものだけをアプリに渡すようになっています。)

SwiftUI[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 の定義

handler: @escaping (PHAuthorizationStatus) -> Void)

変更は、PHAuthorizationStatus の定義にありました。

PHAuthorizationStatus のとりえる値は以下のようになっています。

  • .notDetermined : まだ確認していない状態
  • .restricted : ユーザーが許諾する権限を持っていない状態
  • .denied : 許可しなかった状態
  • .authorized : 許可した状態
  • .limited : 一部のみ許可した状態

最後の、.limited が、iOS14 になって追加されたものです。

新しいオプション .limited とは?

新しく追加された .limited オプションは、一部のみ許可した状態 です。

問題は、この 「一部」 が、過去に一度選択した写真 を意味していることです。(アプリごとに管理されていると思われます)

アプリで、再度写真を選択しようとしても、過去に選んだ写真しか選択できません。

この 過去に一度選択した写真 を変更するためには、以下の手順を必要とするようです。

  1. PHPhotoLibrary.shared().register() を使って、変更検知できるようにする (PHPhotoLibraryChnageObserver に準拠が必要)
  2. PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: ) を使用して、再度選択させる
  3. PHPhotoLibraryChnageObserver.photoLibraryDidChange が呼び出されるので、変更に応じて処理する
MEMO
iOS14 で導入された PHPickerViewController を使うのであれば、上記の複雑な手順とは無縁です。

まとめ:PHPhotoLibrary.requestAuthorization の変更点@ iOS14

PHPhotoLibrary.requestAuthorization の変更点@ iOS14
  • PHPickerViewController を使うのであれば、requestAuthorization は不要になった
  • requestAuthorization の結果として .limited という状態を取りえるようになった
  • .limited の情報を変更するためには、PHPhotoLibraryChnageObserver というプロトコルと presentLimitedLibraryPicker を使用する必要がある
  • .limited 状態は、ユーザー・開発者 双方に優しくないので PHPickerViewController を使うのが良い。ただし、多くの写真を選択させる時には、PHPickerViewController が理想の UI でない可能性が高いので、要検討。

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です