Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
36
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@akatsuki174

UIImagePickerControllerに代わるPHPickerViewControllerの紹介

WWDC 2020のMeet the new Photos pickerを見たのでメモです。

※ここに出てくるスクリーンショットは、全て上記の動画のものです。

概要

UIImagePickerControllerに代わるピッカーの紹介。このPHPickerを使えばPhoto Libraryへの完全なアクセスがなくても写真や動画を選択することができる。

PHPickerとは

ユーザのPhoto Library内の写真や動画にアクセスすることができるシステム標準のピッカー。

PHPickerには以下の特徴がある。

  • 検索ができる
  • グリッド表示時にズームイン/アウトができる
  • 写真や動画にアクセスするのに一番良い方法
  • まったく新しいデザイン
  • 使いやすいAPI
  • 複数選択ができる
  • フィルター選択が可能

プライバシーへの配慮

写真ピッカーを表示するときに直接Photos Libraryにアクセスを要求する必要がないので、許諾アラートを出す必要もない。

内部の仕組み

PHPickerはアプリ内部で動作しているように見えるが、実際は別プロセスで動いている。
スクリーンショット 2020-07-02 10.16.00.png
アプリはピッカーに直接アクセスすることも、ピッカーコンテンツのスクショを撮ることもできない。ユーザが選択したものだけ、アプリ側は知ることができる。

新しいAPI

PHPickerViewControllerはPHPickerFilterなどの設定を渡されて初期化を行う。ユーザが何かを選択したら、PHPickerは結果を保持しておく用のスペースを作成し、delegateに渡す。
スクリーンショット 2020-07-02 11.06.17.png

コード

まず設定について。選択上限はselectionLimitで指定できる。デフォルトでは1が設定されており、0にすると無制限にできる。アイテムタイプのフィルタリングはfilterで行うことができる。タイプ指定は1つでも、複数でもできる。
スクリーンショット 2020-07-02 11.06.50.png

設定を詰め込んだらPHPickerViewControllerにその情報を渡して初期化する。あとはdelegateを設定して、presentで表示するだけ。
スクリーンショット 2020-07-02 11.14.31.png

ユーザがアイテムを選択し終わったらdidFinishPickingが呼ばれる。まずはピッカーを閉じ、次にNSItemProviderに結果を聞き、期待するオブジェクトがあったら処理をする。このItemProviderは非同期で、エラーが発生したときの処理もここで書く必要がある。
スクリーンショット 2020-07-02 11.19.52.png

デモ

サンプルコードページにあるアプリを使用)

真ん中にUIImageViewのplaceholder、右上に+ボタンがある。今は+ボタンをタップしても何も起きない。
やるべきことは2ステップ。まずは1枚の画像をImageViewに表示できるように、+ボタンがタップされたらピッカーを表示し、選択した写真を貼り付ける処理を書く。次のステップとして、画像が複数枚選択されたときは、画面をタップ時に次の画像を表示するような処理を書く。

受け取った画像(1枚)のハンドリング例は以下の通り。
スクリーンショット 2020-07-02 12.59.32.png

次に複数選択対応をする。itemProvidersで取得したアイテム全てが、iteratorで現在表示されている画像情報がわかるようにする。
スクリーンショット 2020-07-02 14.16.56.png
次の画像を表示するメソッドはこのように書く。
スクリーンショット 2020-07-02 15.36.38.png
単一選択と異なるのはiteratorを使っているかどうかと、delegateの部分。
スクリーンショット 2020-07-02 15.49.00.png
実行するとこのような表示になる。画面下部のボタンをタップすると、今どんな写真がステージされているかがわかる。全ての写真を最初にロードしているわけではないので、読み込み速度は単一のときと変わらない。
スクリーンショット 2020-07-02 15.51.41.png

PHPicker x PhotoKit

PhotoKitベースのアプリの中には、PHAssetsを取得したいと思っているかもしれない。
PhotoKitを使うことでメリットが得られるアプリは、元画像を保持しつつ画像編集を行うアプリや、Photo Libraryの機能を使ったりするアプリ。とはいえPhotos Libraryへのアクセスは必要な場合のみに限定する必要はあるし、アクセスが拒否されたパターンの処理もする必要がある。

実装としては最初にPHPhotoLibraryを使ってPickerを初期化する。callbackを受け取ったらassetIdentifierを取得し、PhotoKitを使ってassetにアクセスできるようにする。
スクリーンショット 2020-07-02 16.26.02.png

Limited Photos Library

iOS 14ではLimited Photos Libraryという新しい機能が使える。もしPhotoKitを使っていなければ特に心配する必要はない。Photo Libraryへのアクセスを求めるアプリでは、既存の選択肢に加え、Photos Libraryの一部のPHAssetsアクセスが許される選択肢が増える。
Limited Phots Libraryを使う場合、注意しなければいけないことがある。ピッカーはPhotos Libraryの全体を表示し、ユーザは全ての写真、動画を選択できるが、ピッカーで何を選択してもアクセスできるPHAssetsは変わらない。より詳しい情報は「Handle the Limited Photos Library in Your App」セッションを参照する。

deprecatedなAPI

AssetsLibraryは数年前からdeprecatedになっているので、PhotoKitに乗り換えを。
新しい発表としては、UIImagePickerControllerの写真ライブラリ部分もdeprecatedになる。代わりにPHPickerViewControllerを採用することをおすすめする。

まとめ

  • 自分で写真動画を選択するピッカーを作るのではなく、PHPickerを採用することをおすすめする
  • PHPickerは複数選択ができる
  • PHPickerだと写真アプリと同じで一貫したUIを提供できるので、ユーザは操作方法がわかっている
  • ピッカーを表示する前に写真ライブラリへのアクセスを要求しない
  • アプリがPhotoKitを利用して写真ライブラリにアクセスしている場合、今一度ライブラリへのアクセスが必要なのか考えたり、代わりにPHPickerを使うようにする
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
36
Help us understand the problem. What are the problem?