Flutter: iOS15.5だとApp Tracking Transparency(ATT)ダイアログが表示されないと言われリジェクト
結論:ATTダイアログの表示前に、簡単な説明ダイアログを表示させる
2022/5/30 Flutter エラー・バグ日記
App Storeの審査に出したら、下記メールが来てリジェクト。
We're looking forward to completing our review, but we need more information to continue. Your app uses the AppTrackingTransparency framework, but we are unable to locate the App Tracking Transparency permission request when reviewed on iOS 15.5.
状況の確認
以前も、iOS15.1でApp Tracking Transparency(ATT)の許可ダイアログ(以下、「ATTダイアログ」)が出ない、と言われてリジェクトされた経験があったので、今回はしっかり実機・シミュレーター両方で表示される事を確認していた。
ちなみにATTダイアログの表示には、「app_tracking_transparency」パッケージを用いている。
まず、使っていたシミュレーターのバージョンを確認すると、iOS15.2だったので、iOS15.5のシミュレーターを探すも、Xcodeのリストに出てこない。
もしや、、、と思い下記ページを確認すると、現在の自分のXcodeのバージョンでは、iOS15.2までしか対応していないと判明した。。
以前、Xcode13にバージョンアップした際、Xcode12も同時並行で動くように、macOSを「Monterey」に上げず、ギリギリ「Big Sur」のまま(Big Sur 11.3)にした影響が出てしまった。
iOS15.5のシミュレーターを動かすには、macOSのバージョンアップ → Xcodeのバージョンアップ の長旅になってしまうので、正直、今はやりたくない。。
メインの検証に使っているiPhoneも、まだアップデートしたくない。
そこで以前も活躍したiPadをiOS15.5にアップデートすることにした。
果たして、アップデートしたiPadで確認すると、確かにATTダイアログは表示されなかった。。
正確には、初回起動時は表示されないが、2回目の起動時には表示される。
連続した許可ダイアログが原因
かなり戸惑ったが、調べたところ、下記情報を拝見して、理由が判明。
自分のアプリでは、ローカル通知機能を使っていたため、アプリ起動時に、通知許可のダイアログを表示させていた。
ATTダイアログは、この直後に表示させる仕様にしていたが、なんとiOS15以降は、許可ダイアログを連続させると、後のダイアログが表示されないらしい。
根拠は、「requestTrackingAuthorization」に関するApple Developerページの以下の記述だと思われる。
"Calls to the API only prompt when the application state is UIApplicationStateActive. The authorization prompt doesn’t display if another permission request is pending user confirmation. Concurrent requests aren’t preserved by iOS, and calls to the API through an app extension don’t prompt."
("APIの呼び出しは、アプリケーションの状態がUIApplicationStateActiveの場合にのみプロンプトを表示します。別の権限リクエストがユーザーの確認を保留している場合、承認プロンプトは表示されません。同時リクエストはiOSによって保持されず、アプリ拡張機能を介したAPIの呼び出しはプロンプトを表示しません。")
以前リジェクトされたとき、アプリが非アクティブの状態だと許可ダイアログを表示できない、ということは理解した。
そのため、今回のアプリでも、ビルド完了後にATTダイアログを出すように設計しており、対処していたつもりだった。。
しかし、上記説明によると、許可ダイアログが表示された状態は、非アクティブ状態と判定されるらしく、これが原因で連続表示できないらしい。
確かに、許可ダイアログの表示中は、アプリ側の操作が一切できないので、アクティブの対象が許可ダイアログ側に移っているのだろう。
2回目の起動時に、ATTダイアログが表示されたことも納得。
しかし、腑に落ちなかったのは、iOS15.2のシミュレーターや実機で、問題なく表示されることを確認していた点。
ネットで調べても、上記仕様(連続ダイアログ不可)は、既にiOS15.1からの仕様であり、iOS15.5以降の仕様であるとの情報はなかった。
iOS15.5で何か変わったのだろうか、、。
対策1 ATTダイアログ表示を遅らせる(うまく行かず)
ともかく、コードの構造を大きく変えたくなかったので、こちらやこちらの情報を参考に、ATTダイアログの表示前に、「await Future.delayed(Duration(seconds: 1));」のように、待ち時間を入れてみた。
しかし、、ATTのダイアログは表示できなかった。
待ち時間をもっと長くすれば良い気もするが、挙動が不自然になるのも困る。
対策2 ATTダイアログ表示の前に、別のダイアログを表示させる(解決)
通知許可の表示タイミングを変更するとか、ATTダイアログの表示タイミングを最初の広告表示前にするとか、修正方法についてかなり悩んだが、試行錯誤の結果、
ATTダイアログの前に、簡単な説明ダイアログを表示させる
という方法で回避することにした。
この方法だと、コードの構造を大きく変える必要がない。
気になるのはユーザー心象の点だが、一般的に、ユーザーからの許可率を高めるために、ATTダイアログの前に誘導的な説明ダイアログを表示させるケースは多いと思われる(AdMobも推奨していた)。
許可を強く促す内容だとリジェクトされる場合もあるらしいので、無用なリジェクト要因を避けるため、自分は割愛していたが、今回の事情を踏まえると、やむを得ない。
そこで、
広告に関するご確認:
広告に関してご確認いただきます(初回のみ)
次へ
とだけ表示する、簡単な「CupertinoAlertDialog」(iOS限定のダイアログなので、iOS風を採用)を、ATTダイアログの前に表示させることにした。
これで無事、iOS15.5においても、アプリ起動時に、
通知許可ダイアログ
→ 「CupertinoAlertDialog」 ※ここでアプリ側がアクティブになる
→ ATTダイアログ
の順番で表示させることができた。
「CupertinoAlertDialog」の表示中、アプリ側を触ることができるので、この時点でアプリがアクティブ状態になっていることが分かる。
そのままApple審査に再提出したところ、問題なく承認された(安堵)。
「CupertinoAlertDialog」の表示内容も問題ないと判定されたようだ。
(後日追記)
本内容は、FlutterアプリでのApp Tracking Transparency(ATT)対応について整理した下記記事にも反映しましたので、よろしければご参照ください。
補足
ちなみに、修正後の挙動チェックのため、アップデートしたiPadに有線でインストールしようとしたが、「Xcodeのバージョンが対応していない」と表示されてできなかった。
しかたなく、修正の都度、App Store Connectにアップロードして、TestFlight経由でiPadにインストールする羽目になった。
やはり、少々大変でもmacOSとXcodeは最新版にしておけば良かったと後悔。。
リリースしたアプリ(全てFlutterで開発)
個人アプリ開発で役立ったもの
おすすめの学習教材
\超初心者向けでオススメな元Udemyの講座/
\キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/
\Gitの基礎について無料で学べる/
おすすめの学習書籍
\実用的。image_pickerに関してかなり助けられた/
\Dartの基礎文法を素早くインプットできる/