Edited at

iOS13 & iOS12で位置情報を「常に許可」してもらうための導線設計に関するあれこれ

※ 実装/動作確認環境: Xcode 11 beta7 + iOS 13 beta 8


TL; DR


  • iOS13 & iOS12で位置情報を「常に許可」してもらう場合、Info.plistの値を以下のようにすることで適切に説明・誘導できそう



    • NSLocationWhenInUseUsageDescription


      • XXXの利用には、「Appの使用中は許可」を選択してください。




    • NSLocationAlwaysAndWhenInUseUsageDescription


      • XXXの利用には、「常に許可」を選択してください。






背景と概要


  • iOS13からは CLLocationManager.requestAlwaysAuthorization() を実行しても、「常に許可」をすぐに取得できないようになり、アラートで2度許可を取得する必要がある


    • 詳細はWWDCの発表内容1や解説記事2 3を参照



  • iOS12もサポートするアプリにおいて、位置情報を「常に許可」してもらうために、2つのアラート(および設定アプリ内)で表示される位置情報の用途について、どのように設定するのが妥当か調査・検討した


(おさらい)位置情報の用途の明示

位置情報を利用するためには、Info.plistに以下のKeyを設定し、用途を明示する必要がある

なお、以下の説明では、簡単のためNSLocationAlwaysAndWhenInUseUsageDescriptionAlwaysNSLocationWhenInUseUsageDescriptionWhenInUseと表記する


表示される値の調査

何らかの方法で2度の確認アラートを回避する方法を模索した(ページ下部参照)が、結局は素直に2度のアラートでの許可取得に乗っかるしかなさそうと判断。

試してみたところ、呼び出すCLLocationManagerのメソッドやInfo.plistの定義内容によって、表示される値が異なるようなので、調査・整理した。


requestWhenInUseAuthorization()の実行で表示される値


iOS12 & iOS13(共通)

表示箇所
表示される値

許可取得アラート
WhenInUse

設定アプリ内※1
下記参照


設定アプリ内で表示される値

Info.plistの定義内容に応じ、表示される値は異なる


  1. Info.plistに WhenInUse のみが定義されている場合



    • WhenInUse の値が表示される



  2. Info.plistに AlwaysWhenInUse の両方が定義されている場合



    • Always の値が表示される


      • 位置情報の利用も「常に許可」が選択可能4






requestAlwaysAuthorization()の実行で表示される値


iOS12

表示箇所
表示される値

許可取得アラート
Always

設定アプリ内※1
Always


iOS13

表示箇所
表示される値

許可取得アラート(1回目)※2
WhenInUse

許可取得アラート(2回目)※3
Always

設定アプリ内※1
Always


  • ※1: 設定 > アプリ名 > 位置情報 のフッターに表示されるもの

  • ※2: {Appの使用中は許可, 1度だけ許可, 許可しない}の3つの選択肢があるアラート

  • ※3: {"使用中のみ許可"のままにする, "常に許可"に変更}の2つの選択肢があるアラート


iOS13 & iOS12で「常に許可」に誘導するための文言設計

上記の調査内容に基づき、以下のような内容にする予定



  • WhenInUse


    • XXXの利用には、「Appの使用中は許可」を選択してください。




  • AlWays


    • XXXの利用には、「常に許可」を選択してください。




このようにしたときの挙動

requestAlwaysAuthorization()のみ利用する想定


  • iOS12



    1. requestAlwaysAuthorization() のアラートで"「常に許可」を選択…"(=Alwaysの内容)が表示される



  • iOS13



    1. requestAlwaysAuthorization() のアラートで"「Appの使用中は許可」を選択…"(=WhenInUseの内容)が表示される

    2. のちに表示されるアラートで"「常に許可」を選択…"(=Alwaysの内容)が表示される




(参考)設定アプリ内の許可状態と取得できるステータスの対応

当初は「常に許可」でなければ設定アプリに誘導する手を検討した。

しかし、WWDC発表内容1等にもある通り、詳細なステータス(WWDC資料ではTemporaryProvisionalと示されているもの)はラップされており、かつ調べてみると想像以上に扱いづらそうなので断念した。

設定アプリ内で参照できる許可状態とアプリ上で取得できる許可ステータスの対応を確認した結果は以下の通り。

設定アプリ内の許可状態※1※2
取得できるステータス※3

(許可取得前)
notDetermined

なし
denied

次回確認(起動中に位置情報の許可取得を行っていない)
notDetermined

次回確認(起動中に「1回だけ許可」を選択)
authorizedWhenInUse

このAppの使用中のみ許可
authorizedAlways

常に
authorizedAlways


  • ※1 表内の文言はiOS13のもの(iOS12とは若干異なる)

  • ※2 ()内の値は本表作成にあたり付記した注釈

  • ※3 CLLocationManager.authorizationStatus()の値

authorizedAlwaysのステータスが「このAppの…」と「常に」に対応するのは、発表内容の通りであり、またプライバシー保護の旗印のもとであればやむなしといった印象。

が、次回確認(起動中に位置情報の許可取得を行っていない)次回確認(起動中に「1回だけ許可」を選択) の状態があり、それぞれ対応するステータスとの入り組み具合を見ると、(自分で書いたものながら)「お前は何を言っているんだ」感がすごい。





  1. What's New in Core Location 



  2. iOS 13ではCLLocationManagerでrequestAlwaysAuthorizationを呼んでも常に許可という選択肢はでない 



  3. iOS13から位置情報の権限周りの挙動が変わるかも 



  4. どの方法で許可を取得しようとしたかではなく、NSLocationAlwaysAndWhenInUseUsageDescriptionの有無で決まる模様。ドキュメントにも、「この値は位置情報へのアクセスを常に行う際に必要」と口酸っぱく念押しのように書かれている。