iOS14「SKAdNetwork」で必要な対応をまとめました。

## 概要

まず「SKAdNetwork」への対応ですが

実際のところ、導入している広告SDK側や計測SDK側で実装されるケースが多いとは思います。

しかし、**各SDK側でどんな対応をしているのか？**については分かっていた方が良いので
(例えばSDK同士の干渉問題が出たりした際など)

- **広告主側**
- **広告表示側(パブリッシャー、媒体側)**
- **広告ネットワーク**

以下にそれぞれの「SKAdNetwork」対応内容について整理しました。


## 最初に、SKAdNetworkとは

```swift
class SKAdNetwork : NSObject
```
「IDFAを使わない広告成果トラッキング」の為に、iOS14で更新されるクラスです。

Appleが提供する広告効果の確認方法となります。

これまでは「どの広告のどのキャンペーンか？」くらいだった粒度の情報が

「どのアプリからきたか？+ α」までわかるようになる予定です。

ただし、Apple公式ということで多くの制限があり

細かなユーザ追跡を基盤に価値を提供してきた計測プロバイダー(MMP)からは

「このクラスは役不足」「この仕組みで満足な計測を行うことは出来ない」との声も多い様です。


## 広告主側アプリでの対応

広告主側は、色々な他社アプリ内に広告を掲載している側のアプリです。

要するに、お金をかけて掲載した**広告効果を計測したい側**です。

Appleのドキュメントでは**「Advertised app」**と表現されています。

インストール（起動）成果の通知処理を実装する必要があります。

### 成果通知の実装

外部SDK内部で実行されているケースが主ではあると思いますが、

アプリ側では起動時に

```swift
class func registerAppForAdNetworkAttribution()
```

または

```swift
class func updateConversionValue(_ conversionValue: Int)
```

を呼び出す必要があります。

どちらでも成果を通知させることが出来ます。

前者の**```registerAppForAdNetworkAttribution()```**は初回呼び出しのみが有効で

後者の**```updateConversionValue(_:)```**では、

任意のコンバージョン値(6bit制限あり)を広告ネットワークへ成果通知と一緒にポストバックすることが出来ます。

この**コンバージョン値の活用方法**としては、こちらが参考になりました。

[Announcing Flurry Conversion Value Analytics for... \| Flurry Blog](https://www.flurry.com/post/626449503277531136/announcing-flurry-conversion-value-analytics-for)

Flurry SDKでは、このコンバージョン値を使って

ユーザを大まかにセグメント分けしたり、比較する方法に加え

**主要なイベントをトラッキング**するオプション機能を提供する様です。

例えば、ログインやアプリ課金などの特定イベント発生時に

**```updateConversionValue(_:)```**を呼び出して
（registerAppForAdNetworkAttributionでスタートした２４hタイマーが切れる前に呼ぶ必要がある。2020/08/20 16:15追記）

↓

コンバージョン値を広告ネットワークへポストバック

という少しイレギュラー？な方法みたいです。

何れにしても、広告ネットワークへの通知が、**リアルタイムでは無い**点には注意が必要です。

> The first call to registerAppForAdNetworkAttribution() generates the notification if the device has attribution data for that app, and starts a 24-hour timer. Subsequent calls to this method have no effect. You may, however, call updateConversionValue(_:) to provide a conversion value and restart the timer.
The device sends the install notification to the ad network’s postback URL within 0-24 hours after the timer expires. Ad networks must verify the postback after receiving it. See Verifying an Install Validation Postback for more information.
[Apple Documentationより](https://developer.apple.com/documentation/storekit/skadnetwork/2943654-registerappforadnetworkattributi#discussion)

とあるので

メソッドトリガーでの24時間タイマースタート ＋ そこから０〜24時間でポストバック

つまり、**最短24時間、最長で48時間のタイムラグ**が発生する可能性があります。

これがもしリアルタイムだと、ユーザーをある程度紐付けする事が出来てしまうので、その対策だと思われます。

少し話が逸れましたが、広告主側アプリとしては

- **成果通知処理の実装(自前実装orSDK)**
- **コンバージョン値の活用(オプション)**

が対応ポイントです。

### コンバージョン値についての補足（2020/08/25：追記）

- **```updateConversionValue(_:)```**は実行する度に24hタイマーはリセットされて延長される

- 最終的に広告ネットワークに送信されるのは、**1番大きい値のコンバージョン値**のみ

例えば、繰り返し**```updateConversionValue(_:)```**を実行したとしても

6ビット制限があるので最大で63回、時間で計算すると64日となる

例）
CV値：01 → CV値：02 → ...　→ CV値：63がタイマー終了後に送信
CV値：02 → CV値：01（このコンバージョン値は無視され送信されない）→ CV値：01がタイマー終了後に送信


## 広告表示側アプリでの対応

アプリ内で広告を掲載しているアプリでの対応です。

メディア系、カジュアルゲーム系などのいわゆる**広告モデル**で収益を上げているアプリです。

Appleのドキュメントでは**「Source App」**という表現されています。

こちら側のアプリでは、掲載する全ての広告ネットワークIDを登録する必要があります。

### Info.plistに広告ネットワークのIDを登録

アプリ内で表示する全ての広告ネットワークIDをInfo.plistに登録します。

このIDは、**広告ネットワーク側へ問合せて**事前に用意する必要があります。

広告ネットワークIDの登録方法は、Info.plistのキーに

```
SKAdNetworkItems
```

を入力。
以下の形式で、**全ての広告ネットワークIDを登録**していきます。

```
<array>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>example100.skadnetwork</string>
    </dict>
    <dict>   
         <key>SKAdNetworkIdentifier</key>
         <string>example200.skadnetwork</string>
    </dict>
</array>

```

広告表示側の対応は、**基本的にこれのみ**です。

しかし、自前で広告を表示する(レアケース？)が必要であれば、以下対応も行います。

### 表示広告に広告ネットワークの情報を紐付ける

広告SDK側で実装されるケースがほとんどだと思いますが

広告表示(インプレッション)時に、後々インストールを検証する為の各キーを設定する必要があります。

広告インプレッション時に

```swift
class SKStoreProductViewController : UIViewController
```
のインスタンスメソッド

```swift
func loadProduct(withParameters parameters: [String : Any], completionBlock block: ((Bool, Error?) -> Void)? = nil)
```

を呼び出し、**parameters**に広告表示するアプリのIDや重複、不正防止用の署名などの値を指定します。

その後は

表示広告のタップが発生

↓

presentで、SKStoreProductViewControllerのインスタンスを表示する
(AppStoreをアプリ内で表示)

という流れがひとつの形になると思います。


## 広告ネットワークでの対応

広告ネットワーク側で開発を行っている場合には対応が必要となってきます。

兎にも角にもまずは、**Appleへ広告ネットワークとして登録し公式に認められる事が必要**となります。

[Appleへの広告ネットワーク登録](https://developer.apple.com/documentation/storekit/skadnetwork/registering_an_ad_network)

[登録申請フォーム](https://developer.apple.com/contact/request/ad-network-id/)

Appleから登録が認められた後に

- 広告ネットワークID（このIDを広告表示側アプリのinfo.plistに設定）が発行

- 公開鍵の共有

- 成果ポストバック用エンドポイントを共有
 [Verifying an Install Validation Postback](https://developer.apple.com/documentation/storekit/skadnetwork/verifying_an_install_validation_postback)

というステップに進む事が可能になります。


## 三者間のコミュニケーションが大事

「SKAdNetwork」対応では、自分だけ（または相手だけ）が対応すれば良いという訳ではなく

- 広告出稿側アプリ

- 広告掲載側アプリ

- 広告ネットワーク

の三者が足並みを揃えて対応する必要があります。

誰かが対応していないと機能しないので、**上手く計測出来ない**状況が簡単に起こります。

ただ、広告や計測に対するモチベーションも三者三様なので

ここに社内事情や意思決定のスピードのばらつき等がプラスされてしまうと、

状況は更に複雑(カオス)になってしまうのでは？と思います。

また

- **成果のポストバック送信がリアルタイムではない**（恐らくランダムで毎回違う）

という点もトラブルの原因特定を難しくさせそうです。



---

参考：
[SKAdNetwork](https://developer.apple.com/documentation/storekit/skadnetwork)
[Ad Network Install Validation Keys](https://developer.apple.com/documentation/storekit/skadnetwork/ad_network_install_validation_keys)
[Configuring the Participating Apps](https://developer.apple.com/documentation/storekit/skadnetwork/configuring_the_participating_apps)