6
4

More than 3 years have passed since last update.

Flutterでの広告ID取得に関して考える (Android/iOS)

Last updated at Posted at 2021-05-19

最近、iOSではiOS14.5からApp Tracking Transparency(名称が長いのでこの先はATTと略す)に対応しないと完全にIDFAの取得ができなくなりました

iOS 14.5以上サポートしているアプリではATT対応はもちろん必要ですが、サードパーティ製の広告SDKを使わずに会社独自の広告配信基盤などを持っている場合は標準ライブラリを使って広告IDを取得するケースがあると思います (基本、広告SDKが内部的に広告IDをよしなに取得してくれてるイメージ)

両OS含めてFlutterで取得する場合はどうすればいいかと気になり、調べたので簡単にまとめてみます

環境

  • Flutter 2.0.4
  • Dart 2.12.2

広告ID取得のパッケージ

スコア高め(Pub Point 110 / Popularity 80以上)とNull Safety対応しているかの点で以下の2つかなと思いました

使い分けに関してですが

  • AAIDを取得したい → advertising_id
  • (あんまりないケースだと思いますが) iOS 14未満でASIdentifierManagerクラスの有効フラグも使ってIDFAを取得したい → advertising_id
  • iOS 14以上でIDFA取得したい → app_tracking_transparency

ちなみに advertising_idパッケージも内部的にATT対応( requestTrackingAuthorization メソッド呼んでるなど)しているのでiOS 14でも使えます

大まかな違いがATTのAuthorizationStatusがFlutter側で使えるか使えないかになります

AAIDの取得

以下のパッケージをインストールします

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  advertising_id: ^2.0.0

有効フラグは AdvertisingId.isLimitAdTrackingEnabled
AAIDは AdvertisingId.id で
それぞれの値が返ってくるので以下のコードで実現できます

  final _notAdID = '取得失敗用文字列';

  Future<String> _getAdIDByAndroidPlatform() async {
    try {
      final isTrackingEnable = await AdvertisingId.isLimitAdTrackingEnabled;

      // 有効でなければ取得しない
      if (isTrackingEnable != null && !isTrackingEnable) {
        return _notAdID;
      }

      final aaid = await AdvertisingId.id(true); // Future型で返ってくる

      if (aaid == null) {
        return _notAdID;
      } else {
        return aaid;
      }
    } catch (e) {
      print(e);
      return _notAdID;
    }
  }

ビルドして確認する際は
端末の設定アプリ > Google > 広告 の画面のスイッチボタンでオプトイン/オプトアウトして確認してください

IDFAの取得

以下の広告IDを取得するパッケージと端末情報を取得するパッケージをインストールします

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  app_tracking_transparency: ^2.0.0+1
  device_info: ^2.0.0

Flutterで以下のようなOSを判定するコードは存在しますが、

    if (Platform.isAndroid) {
      // Android
    } else if (Platform.isIOS) {
      // iOS
    } else {
      // 他プラットフォーム (例 Webとか)
    }

OSのバージョンまで判定するコードが標準にはないです
device_infoパッケージを使ってOSバージョンを取得できるので、それを使ってバージョン判定するコードを自作できます

iOSでは以下のコードで端末のOSバージョンを取得できます

  Future<String> getIOSOSVersion() async {
    try {
      final iOSInfo = await DeviceInfoPlugin().iosInfo;
      return iOSInfo.systemVersion;
    } on PlatformException {
      // 失敗
    }
  }

また、3桁のバージョン比較はこちらの記事が参考になるのでこの記事では割愛します

app_tracking_transparency パッケージでは以下の3つのことができます

  • IDFAの取得 AppTrackingTransparency.getAdvertisingIdentifier()
  • ATTのステータス AppTrackingTransparency.trackingAuthorizationStatus
  • ATTのパーミッションリクエスト AppTrackingTransparency.requestTrackingAuthorization()

以下のコードで場合分けして取得するのがいいと思います

final _zeroID = '00000000-0000-0000-0000-000000000000';
final _notAdID = '取得失敗用文字列';

  Future<String> _getAdIDByIOSPlatform() async {
    try {
      final osVersion = await deviceInfoRepository.getIOSOSVersion();

      // iOS 14.5以上なら
      if (/*バージョン判定コード*/) {
        final TrackingStatus trackStatus =
            await AppTrackingTransparency.trackingAuthorizationStatus;

        // 初めての場合はATTのパーミッションリクエスト
        if (trackStatus == TrackingStatus.notDetermined) {
          final status =
              await AppTrackingTransparency.requestTrackingAuthorization();

          if (status == TrackingStatus.authorized) {
            return AppTrackingTransparency.getAdvertisingIdentifier();
          } else {
            return _notAdID;
          }
        }
      }

      // iOS 14 ~ 14.5未満なら
      if (/*バージョン判定コード*/) {
        final status =
            await AppTrackingTransparency.trackingAuthorizationStatus;

        if (status == TrackingStatus.notDetermined ||
            status == TrackingStatus.authorized) {
          return AppTrackingTransparency.getAdvertisingIdentifier();
        } else {
          return _notAdID;
        }
      }
      // iOS 14.0未満のバージョンは
      final idfa = await AppTrackingTransparency.getAdvertisingIdentifier();

      // 取得失敗すると00000~~が返ってくる
      if (_zeroID == idfa) {
        return _notAdID;
      } else {
        return idfa;
      }
    } catch (e) {
      print(e);
      return _notAdID;
    }
  }

気を付けるポイントは ATTは使用できますが、iOS 14.0 ~ 14.5未満の間ならパーミッションリクエストしなくても端末の設定に応じてIDFAができます 
オプトアウトしている場合は Tracking.deniedが返ってきます

iOS 14未満の場合は文字列の比較をしてあげるとよいです
オプトアウトしている場合にIDFA取得しようとすると0000~が返ってくるので、文字列一致の判定でオプトイン/オプトアウトの判定できます

また、ATTのパーミッションのリクエストする際はInfo.plistで文言の設定も必要になってくるので忘れずに設定しましょう

Info.plist
<dict>
    <key>NSUserTrackingUsageDescription</key>
    <string>IDFA取得しますよ</string>
</dict>

スクリーンショット 2021-05-20 10.19.51.png

初めてリクエストする際はこのように表示されます

もし何か間違っている箇所があれば気軽にご指摘お願いします :pray:

参考にした記事

iOS14でのIDFA取得
[iOSアプリ開発] バージョン番号を比較する仕組みを作る

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4