Facebook Audience NetworkのiOS14対応



Facebook Audience NetworkのiOS14対応がめんどくさかったのでメモする。

#問題
iOS14でFacebook Audience Networkの動画広告を再生できない。

#結論

Facebook Audience NetworkのSDK
FBSDKCorekit

を最新にして、適当なタイミングで

```
[FBAdSettings setAdvertiserTrackingEnabled:YES];
```
を実行する。

#詳細

## iOS14の変更点

iOS14で広告関連に強い影響を与える変更がはいる予定だったが、それが延期された。

広告のターゲティングのためにIDFAと呼ばれるものが使われているが、これをアプリ側が使うためにユーザーの許可が必要になるはずだった。
本来ならこの変更に対応する必要があった。メデュエータ、アダプター、各社SDKの更新などが必要になるはずだったが、土壇場になってAppleが延期を発表した。

なので、少なくとも2020年内は特に対応が不要で、iOS14のためにSDK群を特に更新する必要はなくなったはずだった。

が、Facebook Audience NetworkはSDK群を最新にする必要があるようだった。

##Facebook Audience Networkの挙動

Facebook Audience Networkの動画広告を再生するためにはいくつかの条件がある。

- Facebookアプリがインストールされていてログインしていること。
- ターゲティングが許可されていること。
である。

ターゲティングが許可されているかどうかの判定はFacebook Audience Networkが依存するFBSDKCorekit内のFBSDKAppEventsUtilityの

https://github.com/facebook/facebook-ios-sdk/blob/cdb8c71fb7f22b4f1af05c21246c12c1aa49f89e/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m#L119

```
+ (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus
{
  static dispatch_once_t fetchAdvertisingTrackingStatusOnce;
  static FBSDKAdvertisingTrackingStatus status;

  dispatch_once(&fetchAdvertisingTrackingStatusOnce, ^{
    status = FBSDKAdvertisingTrackingUnspecified;
    Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass();
    if ([ASIdentifierManagerClass class]) {
      ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager];
      if (manager) {
        status = manager.advertisingTrackingEnabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed;
      }
    }
  });

  return status;
}
```

で判定していると思われる。これじゃないとしてもおそらく似たようなコードのはず。コードを見ればわかるが、ターゲティングが許可されているかどうかは `ASIdentifierManager::isAdvertisingTrackingEnabled`で判定されるようす。

##Facebook Audience Networkの問題

この`isAdvertisingTrackingEnabled`の挙動がiOS13以下と14で異なるようだ。iOS14では常にfalseを返すのが仕様。
https://qiita.com/yofuru/items/213b88b85553631204e4#%E3%81%A4%E3%81%BE%E3%82%8A%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E3%81%93%E3%81%A8


なので、この仕様変更に対応しなければ、Facebook Audience Networkはターゲティングが許可されていないと判断されて広告の再生ができない。たぶん。

##解決法

この問題はFacebook Audience Network SDK v6系で解決される。

`FBAdSettings::setAdvertiserTrackingEnabled`が追加されたのでこれを使う。適当なタイミングで

```
[FBAdSettings setAdvertiserTrackingEnabled:YES];
```

とすればFacebook Audience Networkの動画広告を再生することができた。

とりあえずアダプターの初期化処理の中で設定しておくのが無難な気がする。

```
- (void)initializeNetworkWithConfiguration:(NSDictionary<NSString *, id> *)configuration
                                  complete:(void(^)(NSError *))complete {
    FBAdInitSettings *fbSettings = [[FBAdInitSettings alloc]
                                    initWithPlacementIDs:configuration[kFacebookPlacementIDs]
                                    mediationService:[FacebookAdapterConfiguration mediationString]];
   
    // トラッキングを許可
    [FBAdSettings setAdvertiserTrackingEnabled:YES];
    
    [FBAudienceNetworkAds
     initializeWithSettings:fbSettings
     completionHandler:^(FBAdInitResults *results) {
         if (results.success) {
             MPLogDebug(@"Initialized Facebook Audience Network");
             complete(nil);
         } else {
             NSError *error =
             [NSError errorWithDomain:@"FacebookAdapterConfiguration"
                                 code:0
                             userInfo:@{NSLocalizedDescriptionKey : results.message}];
             complete(error);
         }
     }];
    
    if (configuration != nil && [configuration count] > 0) {
        FacebookAdapterConfiguration.isNativeBanner = [[configuration objectForKey:@"native_banner"] boolValue];
    }
}
```

本来ならダイアログを表示してユーザーに許可を得る必要があるが、そこまでするするべきなのか、決め打ちでYESを設定してしまうのがいいのかは不明。

めんどうだから決め打ちで実装してしまっても良い気がする。未確認だし可能性は薄いと思うが、GDPRみたいにどこかの外国の法律にひっかかったり、Appleの審査で弾かれたりするかも。