👻

FlutterでATT(App Tracking Transparency)をサクッと対応

2021/07/07に公開

FlutterでATT(App Tracking Transparency)をサクッと対応

タイトル通りです。
ATTっていうのはこいつのことですね。

iOSでユーザーの情報と収集する際には出す必要があります。
収集しているのにこれがないと審査で「これ追加してね☆」ってリジェクトされます。
また、iOS14.5以上ではこいつで許可されないとIDFAが使用できないとのことで広告を使ってる方々は対応必須でしょう。

iOS独自のものだからFlutterでの実装は結構面倒なのでは?
となりそうなところですが、すでにapp_traking_transparencyというパッケージを作ってくださっているのでこちらを使ってサクッと実装していきます。

インストール

まずは上のパッケージをインストールしていきます。

$ flutter pub add app_tracking_transparency

Info.plistを編集

直接編集する場合

次にios/Runner/Info.plistを編集していきます。
VSCodeなどでInfo.plistを直接開き、以下のように編集します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<!-- 略 -->
    <key>NSUserTrackingUsageDescription</key>
    <string>表示する広告を適切に選択するために使用します。</string>
</dict>
</plist>

XCodeを使って編集する場合

もしくは、XCodeでiOSプロジェクトを開き、その中のInfo.plistを編集することもできます。著者はこっちの方がわかりやすいのでもっぱらXCodeでやっています。

XCodeで設定する場合は、Info.plistのアイテムをホバーした際に出るプラスボタンをクリック。
図1

そして、Keyの欄にPrivacy - Tracking Usage Descriptionを入力します。(それか一覧が出るので選択する。)
あとは、Valueの欄に何かしらトラッキングする際の用途や説明などの文言を記入すればOKです。

ちなむと、ここの説明が不十分だったり不明瞭だったりすると審査に落とされるので注意です。
著者が最近作ったアプリでは「表示する広告を適切に選択するために使用します。」で審査に通りました。
まあ参考程度くらいにしておいてください。

実装

ようやく実装です。といっても大したことはしません。関数を一つ定義するだけです。

class _MyHomePageState extends State<MyHomePage> {
  // 略
  
  Future<void> initPlugin() async {
    final status = await AppTrackingTransparency.trackingAuthorizationStatus;
    if (status == TrackingStatus.notDetermined) {
      await Future.delayed(const Duration(milliseconds: 200));
      await AppTrackingTransparency.requestTrackingAuthorization();
    }
  }
  
  // 略
}

一処理ずつ解説していくと、まず

final status = await AppTrackingTransparency.trackingAuthorizationStatus;

で現在のトラッキングのステータスを取得してきています。

if (status == TrackingStatus.notDetermined) {
  await Future.delayed(const Duration(milliseconds: 200));
  await AppTrackingTransparency.requestTrackingAuthorization();
}

そして、そのステータスがまだ未定義(=トラッキングについての許可がまだ決定されていない)の場合のみにATTのダイアログを代用な処理になっています。

この関数を呼び出すのはinitStateで呼び出します。


void initState() {
  super.initState();
  // Can't show a dialog in initState, delaying initialization
  WidgetsBinding.instance?.addPostFrameCallback((_) => initPlugin());
}

WidgetsBinding.instance.addPostFrameCallbackが何かと簡単にいうとBuild後に呼び出されるコールバックを渡せる関数です。
こいつにinitPlugin関数を渡すことでBuild後に確認のダイアログが出てくれるようになるわけですね。

著者はsplashscreenというパッケージを併用していたので、ここのnavigateAfterFutureinitPlugin関数を渡していましたが問題なくできました。

ここまでで完成です!
実際にビルドしてみると最初にこんな感じの画面がでてくれば成功です。

終わりに

最初リジェクトされた時は対応めんどくさ。。。と思っていたのですが割とサクッとできたので助かりました。

Discussion