WWDC2020での許諾周りのアップデートまとめ

# 概要

今年はプライバシー、権限周りで多くのアップデートがあったのでまとめてみます。

この記事は以下のWWDC 2020セッション動画、及び公式ドキュメントを元に書いています（ここで出てくるスクショも動画のものです）。
周辺知識も含めて深く知りたい方はご参考までに。

* [Build trust through better privacy](https://developer.apple.com/videos/play/wwdc2020/10676/)
* [Meet Nearby Interaction](https://developer.apple.com/videos/play/wwdc2020/10668)
* [Design for location privacy](https://developer.apple.com/videos/play/wwdc2020/10162)
* [What's new in location](https://developer.apple.com/videos/play/wwdc2020/10660/)
* [Handle the Limited Photos Library in your app](https://developer.apple.com/videos/play/wwdc2020/10641/)
* [AutoFill everywhere](https://developer.apple.com/videos/play/wwdc2020/10115)

なお、IDFAに関してはすでに多くの記事が出ているので省きます。

# 所感

今までよりいっそう、「必要な分だけの権限をもらう」感が強くなった

# 背景

* アプリがアクセスできる情報量とユーザ体験のバランスを取りやすくしたい
* iOS 13までは許諾アラートが出てきたらYesと答えないとアプリのコア機能を使えないこともあった

# 写真

## 写真共有アプリの例

iOS 13の場合、写真ライブラリ全体へのアクセス権限を求めることになる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/50f0a72f-d5c6-626e-24d3-08e7382d8a92.png" width="320px">
iOS 14からはLimited Photos Libraryが使えるようになり、ユーザが選択した写真しかアプリからアクセスできない状態を作ることができる。ちなみに[フォーラムの回答](https://developer.apple.com/forums/thread/652303)によると、「選択した写真のみ」の選択肢はオプトアウトできないとのこと。さらに、今回の変更は、新しいAPIや機能を採用していないアプリでも、iOS 14端末だったら影響を受けてしまう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/d7b96e5c-ca89-9446-1c79-821d7b585d81.png" width="320px">
「Select Photos」を選択するとこのようなピッカー（`PHPickerViewController`）が表示される。このときピッカーは別プロセスで起動されており、選択し終わった写真しか知ることができない。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/85f908d0-9fe7-673b-b859-c018f5fabfad.png" width="320px">

## PHPicker

`PHPicker`は`UIImagePickerController`に置き換わる新しいフレームワーク。PHPickerには検索機能、複数選択機能などを備わっている。加えて、写真ライブラリへのアクセス権を必要としないので、許諾アラートを表示する必要もない。アプリがすべての写真にアクセスする必要がない限りPHPickerを使うことが推奨されている。

## アクセスレベル

ステータスは既存のものに加え、`.limited`ステータスが増えている。→[PHAuthorizationStatus](https://developer.apple.com/documentation/photokit/phauthorizationstatus)
これとは別にiOS 14からは[PHAccessLevel](https://developer.apple.com/documentation/photokit/phaccesslevel)というアクセスレベルを指定するenumが登場した。`.addOnly`を指定した場合は左、`.readWrite`を指定した場合は右の許諾アラートになる。
<img width="573" alt="スクリーンショット 2020-08-09 22.49.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/36904807-44c1-ceea-3d11-0b63e8d48b67.png">

今までのステータス確認APIには更新が入り、アクセスレベルの指定が必要になっている。ユーザが`.limited`になっているかどうかは以下のように確認する。
<img width="638" alt="スクリーンショット 2020-08-09 23.10.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/7cd5e7b6-979a-e204-ae8a-9bb0634b8739.png">
許諾リクエスト処理は、ステータス問い合わせと同じようにアクセスレベルを指定する。これにより許諾アラートが表示されるようになる。
<img width="690" alt="スクリーンショット 2020-08-09 23.21.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/90ec5eab-a4f9-9815-c6f2-ac64ef1ff3f2.png">

従来のAPIは将来的に非推奨なAPIになる。従来のAPIのままだと、ユーザが「選択した写真のみ」で許可した場合、`.limited`ではなく`.authorized`を返してしまう。
基本的には`.authorized`と`.limited`では同じように動くべきだが、`.limited`ではユーザのアルバムを作成、取得できなかったり、クラウド上のコンテンツやアルバムにアクセスできなかったりするので注意が必要。

## 許諾範囲の変更

設定アプリから変更することができる。
<img width="320px" alt="スクリーンショット 2020-08-09 21.34.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/801490e6-3906-1192-e357-f0d03d132887.png">
新しいAPIに何も対応を入れていないアプリで、ユーザが「選択した写真のみ…」にした場合は、アプリのライフサイクルごとに一度、PhotoKitのコンテンツにアクセスする時に、現在の選択範囲を維持するか、変更するかを問うアラートが出てくる。
<img width="320px" alt="スクリーンショット 2020-08-09 21.40.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/3f5d93ce-54f4-5b0f-0d1f-747f983795c7.png">
選択UIを手動で表示させて許諾範囲を変更する方法もある。
<img width="470" alt="スクリーンショット 2020-08-10 12.02.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/23396db8-6b6b-75b1-0bee-a3fe39e58872.png">
※[ある記事](https://mackuba.eu/2020/07/07/photo-library-changes-ios-14/)によると、フォトライブラリへのフルアクセスを必要とするアプリは、ステータスが`.limited`の場合、この選択UIを表示させるためのボタンを表示しないといけないといけないと書いているが、それに該当しそうな公式文章は見つけられなかった。

## 許諾アラートを毎回表示させないためには

`PHPhotoLibraryPreventAutomaticLimitedAccessAlert`を`info.plist`に書いておけば、アクセスの拡張を促すアラートが自動で出てくることはなくなる。

# 位置情報

## 近くにいる人に写真を送るアプリの例

写真を共有したい友達を見つけるために位置情報を使用するアプリを考える。iOS 13では以下の許諾アラートだった。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/23259e72-1930-dd44-5064-10a72cdc6d03.png" width="320px">
iOS 14ではおおよその位置情報だけをアプリと共有できる機能が追加される。Precise設定をOFFにすると、おおよその位置情報の更新のみアプリに通知される。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/4ce564b7-cc35-16e1-4caf-257674456818.png" width="320px">
ユーザは設定アプリから設定を変更することもできる。
<img width="320px" alt="スクリーンショット 2020-08-09 17.39.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/ad1d6c19-3629-d772-39d0-656708f5b38b.png">

## Apple Mapsの例

Apple Mapsでは「おおよその位置情報の共有」を選択した人には、アプリ起動時にマップ上部に目立つボタンを表示している。このボタンをタップすると許諾アラートが表示される。
<img width="320px" alt="スクリーンショット 2020-08-09 15.28.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/c333a601-60aa-1cf0-6273-9f0e2b508f81.png">
ユーザがアプリ内を回遊し始めるとこのボタンは目立たなくなる。
<img width="320px" alt="スクリーンショット 2020-08-09 17.21.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/5c0b781b-4feb-b308-9db0-33315a4993da.png">

## App clips

App clipのユースケースに特化して新しい位置情報アクセスが設計された。App clipsでは正確な位置情報へのアクセスを行わなくても、例えば間違った店舗のウェイティングリストに入ってないかなどの確認はできる。App clipsが特定の場所で起動されたかどうかをシステムに尋ねる程度なら、許諾アラートを出す必要はない。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/31578876-b9bd-b872-435a-1d6debf1a959.png" width="320px">

## 許諾状況の確認

「いつ」「どの程度」という2軸で許諾状況を確認することができる。
<img width="592" alt="スクリーンショット 2020-08-09 17.53.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/ae23fa50-8a90-5c30-3859-fa9fc76888dd.png">

## 一時的に正確な位置情報をリクエストする

もし正確な位置情報を必要とする機能があるアプリで、ユーザがおおよその位置情報しか共有していない場合は、ユーザに一時的に許諾のアップデートを依頼することができる。
<img width="320px" alt="スクリーンショット 2020-08-10 22.42.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/aa618da6-830b-afb5-2d21-54bbfc98799a.png">
実装としては以下の通り。
<img width="750" alt="スクリーンショット 2020-08-11 9.21.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/50430e59-309b-112e-2ac7-874d6c770b49.png">
一時的に正確な位置情報を求める理由は`info.plist`の`NSLocationTemporaryUsageDescriptionDictionary`に書いておく。
<img width="705" alt="スクリーンショット 2020-08-11 9.22.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/eb1711ec-7ea6-2113-884f-dd361884fac5.png">

# 連絡先

## 写真共有アプリの例

手動で共有したい友達を選ぶために連絡先情報を使用するアプリを考える。iOS 13までは以下の許諾アラートが出るケースもあった。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/8cfbe0d3-2d4b-b6f7-0292-4ec981c6bd9f.png" width="320px">
とはいえ`CNContactPickerViewController`を使っていれば特に許諾を取ることなく連絡先データへのアクセスが可能だった。
iOS 14からは、TextFieldに特定の`textContentType`を指定していた場合、QuickTypeバーに連絡先データベースから取ってきた情報がサジェストされるようになる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/e10186ba-ca87-2541-e6cd-77fd24a2b3d8.png" width="320px">
<img width="409" alt="スクリーンショット 2020-08-10 23.05.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/6d681974-87e7-04ec-92df-f5514e39d948.png">

# NearbyInteraction

NearbyInteractionフレームワークを使うときはBluetoothやネットワークアクセスの使用許可をとる必要はない。その代わり、アプリは1回限りのセッションベースのアクセスを要求する。あるユーザのデバイスと、その近くにいる別のデバイスの両方が許可をしたら、デバイス間がどれくらい離れているのか、どの方向にいるのかなどを知ることができる。この許可は、アプリがフォアグラウンドで使用され続けている限り有効になっている。
<img width="320px" alt="スクリーンショット 2020-08-09 15.10.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/22d8740a-f361-d201-c3c3-a5fa38934fe6.png">