Flutter×AdMob で App Tracking Transparencyを設定する

アプリ

iOS14(14.5?)から無断でのIDFA(広告用に存在する端末毎の固有ID)の利用が出来なくなりました。
AdMobのコンバージョンをトラッキングするために Apple の SKAdNetwork を利用する必要があリます。
もし設定しなければトラッキングができず、ユーザーにとって興味のない広告が表示されるため、トラッキングした場合と比較して収益が低下するようです。

iOS14以降もIDFAを利用したい場合は、ダイアログを表示し、ユーザーに許可してもらう必要があります。
iPhoneユーザーならお馴染みのアレです。

この記事では、Flutter で admob_flutter 2.0.0-nullsafety.1 モジュールを利用して既に広告が表示できている場合を想定しています

文言の設定

広告ネットワークIDの設定

Xcode から Info.plist を開き、画像のように設定します。

  • 既に存在する Information Property List の配下に Key: SKAdNetworkItems を Type: Array で作成
  • その配下に Key: Item 0 を Type: Dictionary で作成
  • Item 0 の配下に Key: SKAdNetworkIdentifier を type: String, Value: cstr6suwn9.skadnetwork で作成

配下に作成するには Key の左に表示される「>」の矢印を押してから+ボタンを押します。
ここは間違えやすいポイントなのでしっかり設定しましょう。
Value の cstr6suwn9.skadnetwork は今後変更される可能性があるのでAdmob のドキュメントを参照すると確実です。

もし広告ネットワークIDを複数設定したい場合は Item 0 と同列に Item 1, Item2… と増やしていけばOKです。

表示される文言の設定

大丈夫そうなら Info.plist を続けて編集していきます。
ダイアログに表示する文言(先程の画像の「有効化すると〜」の部分)の設定です。
Information Property List の配下に
Key: NSUserTrackingUsageDescription
Type: String
Value: This identifier will be used to deliver personalized ads to you.
を作成します。
Valueの部分は別の文言でも構いません。
編集後は⌘Sなどで保存しましょう。

表示される文言の日本語化

ここまでの工程で文言を作成しましたが、英語が書いてあると何やら怪しい感じがして許可したくないと思われてしまいますよね。

という訳で日本語化していきます
英語のままでも良い方は次の章「表示側の設定」まで飛ばしてください。

言語の追加

Localizations に日本語が追加されていない場合は追加します。
Xcode でプロジェクトを開き、Project->Runner->Localizations の +ボタンから Japanese を追加。なんかダイアログが出るので Finish を押します。

画像では既に追加されていますが、「Japanese」が追加されていればOKです。

翻訳ファイルの作成

翻訳ファイルは言語毎に作成する必要があります。
今回は日本語のみ作成します。

翻訳したい Info.plist と同じ階層に Strings File 「InfoPlist.string」 を作成します。
Xcodeから右クリック⇨New File…⇨Strings File ⇨名前を「InfoPlist」で作成しましょう。
New File… の後、検索窓に string と打つとすぐ見つかります。
「.string」が自動で補完されるため、作成後、ファイル名が「InfoPlist.string」となっていることを確認しましょう。

作成したらそのファイルを開き、下記のようにします。

"NSUserTrackingUsageDescription" = "お客様の興味や関心に合わせた広告を表示するためにのみ利用されます。";

右側が英語文の代わりに表示される文章です。
ユーザーに「許可」を押してもらいやすい文言にしましょう。
ただし、App Store Reviewガイドライン5.1.1(iv)「不要なデータアクセスに同意するようユーザーを巧みに誘導したり、だましたり、強制したりすることはできません」とある通り、ユーザーに誤解を招くような文言は禁止されているので気をつけてください。

翻訳ファイルの設定

文言が決まったら、ユーザーの端末の設定が「日本語」の時に上で決めた文言を表示するように設定します。
InfoPlist.string 編集画面右側の Localization の「Localize…」を押します。
なんかダイアログが出るので、「Japanese」を選択し、「Localize」を押します。

表示側の設定

文言は作成しましたが、まだアプリにダイアログは表示されません。
ここでは例としてアプリの初回起動時にダイアログを表示させるようにしたいと思います。

まず、pubspec.yaml ファイルで app_tracking_transparency モジュールをインストールします。

dependencies:
  flutter:
    sdk: flutter
  admob_flutter: ^2.0.0-nullsafety.1
  app_tracking_transparency: ^2.0.1

↑ app_tracking_transparency を追加。
バージョンは最新のものを参照して読み込むようにしてください。
app_tracking_transparency
因みにバージョンを「any」と指定することで常に最新を読み込めるらしいですが、唐突にバグる可能性があるので個人的には非推奨です。

次に main.dart ファイルを編集して、ようやくダイアログを表示することができます。
追加したパッケージの読み込みを忘れないようにしてください。
クラス配下にメソッドを追加し、ビルド時に呼ぶようにします。

import 'package:admob_flutter/admob_flutter.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';


void main() {
  Admob.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  // App Tracking Transparency を表示する
  void showAppTrackingTransparency() async {
    final TrackingStatus status =
      await AppTrackingTransparency.trackingAuthorizationStatus;
    if (status == TrackingStatus.notDetermined) {
      await AppTrackingTransparency.requestTrackingAuthorization();
    }
  }

  @override
  Widget build(BuildContext context) {
    // App Tracking Transparency の表示
    showAppTrackingTransparency();
    return MaterialApp(
      // 以下略

端末の設定を「日本語」にし、アプリを立ち上げると日本語のダイアログが表示されるようになりました。

まとめ

Flutter は便利ですが、AdMob を利用し続けるためにほぼ必須となってしまった App Tracking Transparency の対応が思ったより大変で苦労しました。
今後もアプリを開発する上で苦労したことを記事にしていくつもりです。

おまけ

ダイアログを表示する前にダイアログを表示する方法(?)

例のダイアログを表示する前に、「次に表示されるダイアログで承認を押してください!」的なダイアログを表示する方法です。

先の例とは異なり、 showAppTrackingTransparency() を下記のように変更し、MaterialApp の後のクラスで呼ぶようにします。
MaterialApp の home: の中で呼ばれるクラス(もしそれが Stateful なら、その State クラス)の Build の先頭です。
例えば、flutter の立ち上げ直後なら _MyHomePageState クラスの Build の先頭になります。

  void showAppTrackingTransparency(context) async {
    final TrackingStatus status =
      await AppTrackingTransparency.trackingAuthorizationStatus;
    if (status == TrackingStatus.notDetermined) {
      if (await showCustomTrackingDialog(context)) {
        await Future.delayed(const Duration(milliseconds: 200));
        await AppTrackingTransparency.requestTrackingAuthorization();
      }
    }
  }

自作ダイアログを表示させますが、自作ダイアログがフェードアウトしている最中に本命のダイアログが表示されてしまうので、 Duration で本命のダイアログの表示を遅延させています。
自作ダイアログは同クラス内に好きなように作成しておきます。
例 ↓

  Future showCustomTrackingDialog(BuildContext context) async =>
      await showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Text(
            'ここにタイトル'
          ),
          content: const Text(
            '次に表示されるダイアログで許可をタップしてください。',
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context, false),
              child: const Text("いやです"),
            ),
            TextButton(
              onPressed: () => Navigator.pop(context, true),
              child: const Text('分かったよ'),
            ),
          ],
        ),
      ) ?? false;


どちらをタップしても、直後に本命のダイアログが表示されます。
気合を入れて凝るのも良いですが例外が発生すると困るので、凝る場合は PlatformException などで捕捉するようにすれば安心です。

参考情報:
Google AdMob iOS 14 以降に備える
Apple Developer SKAdNetwork
Apple Developer ユーザーのプライバシーとデータの使用
App Store Reviewガイドライン

タイトルとURLをコピーしました