SKAdNetworkコンバージョンバリューのマッピング:動的SKANスキーマの自動化

opoinstall
2026-08-25
5 min read

MMPはどのようにSKAdNetworkスキーマを自動的にマッピングするのでしょうか? モバイル計測パートナー(MMP)やアトリビューションのバックエンドは、アプリ内イベントや収益ティアーを統合コンソール上の動的でバージョン管理されたJSON設定スキーマに変換することで、SKAdNetworkのスキーママッピングを自動化します。モバイルSDKは起動時にこの設定を取得し、ランタイム時にローカルでコンバージョンルールを評価するため、対応するコンバージョンルールの変更を、新規のバイナリビルドのリリースなしに即座に反映させることができます。

SKAdNetworkのコンバージョンバリュー・スキーマは、収益トランザクション、オンボーディングのマイルストーン、機能エンゲージメントなどのアプリ内ユーザー行動を、Appleの6ビットの細粒度値(0〜63)および3段階の粗粒度値(lowmediumhigh)にマッピングする、ベンダーまたはアプリケーションレベルのルールセットです。動的マッピングアーキテクチャは、バージョン管理された設定ファイルをクラウドバックエンドからクライアントSDKに配信するため、コンパイルされたiOSアプリバイナリ内にコンロバージョンロジックをハードコードする必要性を排除します。

用語 定義
SKAdNetwork プライバシーを保護しながらキャンペーンアトリビューションを行うためのAppleのプラットフォームレベルのフレームワーク。
コンバージョンバリュー・スキーマ アプリ内イベントのマイルストーンを詳細値と粗い値にマッピングする、ベンダーまたはアプリ定義の設定。
動的スキーママッピング SDKを介したコンバージョンルールの自動配信およびランタイム評価。
ウィンドウロッキング アクティブなコンバージョンウィンドウを早期に確定させるAPIパラメータ(lockWindow: true)。

自動化されたSKAdNetworkコンバージョンバリューマッピングのアーキテクチャ

Appleプラットフォーム層とベンダー・スキーマ層の切り分け

堅牢なコンバージョンバリューエンジンを設計するためには、エンジニアリングチームはAppleのネイティブフレームワークルールとベンダーレベルのスキーマ抽象化を明確に分離する必要があります:

  • Appleプラットフォーム層:最初の起動後における3つの連続するコンバージョンウィンドウ(Day 0〜2、Day 3〜7、Day 8〜35)、6ビットの細粒度値(0〜63)、粗粒度値(lowmediumhigh)、ポストバックデータティアー、およびSKAdNetwork.updatePostbackConversionValue APIを含む、コアオペレーティングシステムのプリミティブを管理します。
  • ベンダー・スキーマ層:収益のバケティング、オンボーディングファネルの進行、ビット単位のフラグ割り当て、リモートJSON同期、クライアントサイドでのルール評価など、アプリケーション固有のビジネスルールを網羅します。
┌────────────────────────────────────────┐
│                           Vendor Schema Layer                                  │
│  [MMP / Analytics Console] ──► [Publishes Versioned JSON Configuration]     │
│                                              │                                │
│  [Client Mobile SDK]       ──► [Evaluates In-App Events Locally in Memory]  │
└──────────────────────────────────────┬─┘
                                       │ (Calculates Fine, Coarse, & Lock)
                                       ▼
┌────────────────────────────────────────┐
│                           Apple Platform Layer                                 │
│  [StoreKit Framework]      ──► [SKAdNetwork.updatePostbackConversionValue]  │
│  [Operating System]        ──► [Manages Conversion Windows & Timers]        │
│  [System]                  ──► [Prepares and Sends Signed Postback]         │
└────────────────────────────────────────┘

MMPコンソールからStoreKitへの動的SKANスキーママッピング

コンバージョンロジックをハードコードする弊害

iOSアプリケーションのターゲット内に直接コンバージョンロジックをハードコードすると、運用上の大きな制限が生じます:

  • App Store審査への依存:収益閾値、イベントの重み付け、ウィンドウロックのトリガーなどを変更するには、バイナリの完全なリリースサイクルが必要になります。
  • バージョンの断片化:本番環境に存在する複数の過去のアプリバージョンが競合するコンバージョンセマンティクスを送信し、下流のレポートモデルを破損させます。
  • 最適化の硬直化:グロースチームは、リアルタイムのマーケティング成果に応じて、エンゲージメント重視のキャンペーンと収益化重視のキャンペーンの間でコンバージョン戦略を柔軟に調整することができません。

動的設定配信パイプライン

自動化されたマッピングアーキテクチャでは、マルチステージのパイプラインを通じて、コンバージョンロジックをコンパイル済みバイナリから切り離します:

  1. コンソール設定:マーケターやアナリストが、一元化されたダッシュボード上でイベントの重み付け、通貨ティアー、ウィンドウロックのルールを設定します。
  2. スキーマのバージョン管理とピン留め:バックエンドがバージョン管理されたJSON設定ペイロードを公開します。ユーザーの35日間にわたるコンバージョンライフサイクル全体でセマンティックのズレを防ぐため、堅牢なベンダー実装では初期コンバージョンウィンドウで確立されたアクティブなスキーマ設定をピン留めし、アプリの再起動後でも正確なマッピングルールが確実に維持されるようにします。
  3. クライアントでの取り込みとキャッシュ:モバイルSDKはアプリの初期化時にアクティブなスキーマをダウンロードし、設定ペイロードとバージョンメタデータの両方をローカルの永続ストレージにキャッシュします。
  4. ローカルルール評価:アプリ内イベントが発生すると、SDKはイベント実行パスに追加のリモート設定リクエストを発生させることなく、キャッシュされたルールセットに対してローカルで評価を行います。

ハードコードされたSKANロジックと動的スキーマ設定の比較

関連記事:SKAdNetwork ──> モバイルアトリビューションアーキテクチャ

SKAN 4.0のウィンドウ全体における動的コンバージョンバリュー・スキーマの設計

マルチウィンドウのスキーマパーティショニング

SKAdNetwork 4.0では、アプリの初回到起点を基準とした3つの連続するウィンドウにわたってコンバージョン計測を構造化しています:

  • ウィンドウ1(Day 0〜2):初回到起動後から最初の48時間。
  • ウィンドウ2(Day 3〜7):初回到起動後48時間から168時間まで。
  • ウィンドウ3(Day 8〜35):初回到起動後168時間から840時間まで。

動的スキーマエンジンは、これらのウィンドウ全体にわたってルールをパーティショニングし、アプリの初回到起動からの経過時間に基づいて適切な値の計算を実行します。

ウィンドウ1(Day 0〜2):細粒度値と粗粒度値の構造化

ウィンドウ1は、細粒度(高精度)のコンバージョンバリューを開示する資格を持つ唯一のコンバージョンウィンドウです。ウィンドウ1の設定では、2つの並行するマッピングが定義されます:

  • 細粒度マッピング(0〜63):初期の収益化ティアー、オンボーディングのマイルストーン、または複合的なエンゲージメントスコアを捉える高解像度のルール。
  • 粗粒度マッピング(lowmediumhigh:割り当てられたポストバックデータティアーで細粒度のレポートが許可されていない場合に開示される、低粒度のフォールバック状態。

ウィンドウ2(Day 3〜7)およびウィンドウ3(Day 8〜35):粗粒度ライフサイクルのトラッキング

第2および第3のポストバックでは、細粒度値は公開されません。適格なデータティアーに対しては、粗粒度値のみが開示されます。

ウィンドウ2および3のスキーマは、長期的なリテンションおよび収益化のマイルストーンに焦点を当てています:

  • ウィンドウ2の粗粒度マッピング:中盤ファネルのリテンションを評価します(例:low = Day 3〜7にアクティブ、medium = 3回のセッションを完了、high = リピート購入またはトライアルからコンバージョン)。
  • ウィンドウ3の粗粒度マッピング:ロングテールのリテンションとサブスクリプションの更新を評価します(例:low = Day 8〜35に継続、medium = レベルのマイルストーンに到達、high = 有料サブスクライバーとしてアクティブ)。

コンバージョンスキーマを設定する開発者は、マルチウィンドウのルール構造に関する技術的ガイドラインについて、SKANコンバージョンマッピングのドキュメントを参照できます。

SKAN 4のコンバージョンウィンドウにおける細粒度および粗粒度値のマッピング


ベンダー定義のエンコードモデル:収益バケティング、ファネル、ビット演算ロジック

これらのエンコードモデルは、Appleが指定したスキーマタイプではなく、ベンダーおよびアプリケーションレベルのデザインパターンを表しています。

収益ベースのスキーマ

収益スキーマは、利用可能な細粒度値を累積購入額に割り当てます:

  • リニアバケティング(線形):収益の範囲を均等な間隔に分割します(例:$96.00まで$1.50刻みで64のバケット)。予測可能なトランザクション規模を持つアプリに最適です。
  • 対数バケティング:低価格の購入には詳細なバケットを割り当て、高額な取引にはバケットの範囲を広げます(例:値1〜20は$0.99〜$19.99、値21〜50は$20.00〜$100.00、値51〜63は$100.00〜$1000.00以上をカバー)。
  • パーセンタイルベースのバケティング:過去のユーザー購入分布を、経験的な収益化曲線に基づいてコホートセグメントにマッピングします。

ファネル進行スキーマと値の方向性

SKAdNetwork 3以前では、Appleはコンバージョンバリューが単調増加することを義務付けていました。SKAdNetwork 4.0では、Appleはこの制限を撤廃し、ウィンドウ1のコンバージョンバリューが後続のAPI呼び出しにおいて増加または減少することを許可しています。

しかし、多くのアトリビューションスキーマでは、より高い値がより進んだ商業的成果を確実に表すようにするため、ベンダーレベルのデザイン規約として意図的に単調増加を強制しています:

  • 0:アプリのインストールと起動。
  • 10:登録完了。
  • 20:オンボーディングチュートリアル終了。
  • 30:支払い方法の追加。
  • 45:カートにアイテムを追加。
  • 63:初回チェックアウト完了。

ビット単位のカテゴリカル・スキーマ

ビット単位のスキーマは、6ビットの整数(26=642^6 = 64)を6つの独立したブールフラグ(b5b4b3b2b1b0b_5 b_4 b_3 b_2 b_1 b_0)として扱います:

ビット位置 バイナリの重み マッピングされたアプリ内行動
ビット 0(b0b_0 1(0b000001) ユーザーが登録を完了した
ビット 1(b1b_1 2(0b000010) ユーザーがプッシュ通知を有効にした
ビット 2(b2b_2 4(0b000100) ユーザーがウィッシュリストにアイテムを追加した
ビット 3(b3b_3 8(0b001000) ユーザーが紹介リンクを共有した
ビット 4(b4b_4 16(0b010000) ユーザーがアプリ内購入を完了した
ビット 5(b5b_5 32(0b100000) ユーザーがプレミアムトライアルに登録した

以下のバージョン管理されたJSONペイロードは、マルチウィンドウの動的設定ドキュメントを示しています:

{
  "schema_version": "4.0.1",
  "app_id": "1234567890",
  "currency": "USD",
  "windows": {
    "window_1": {
      "mode": "hybrid_revenue_and_funnel",
      "fine_mapping": [
        { "event": "app_open", "min_revenue_cents": 0, "fine_value": 0, "lock": false },
        { "event": "registration_complete", "min_revenue_cents": 0, "fine_value": 10, "lock": false },
        { "event": "tutorial_complete", "min_revenue_cents": 0, "fine_value": 20, "lock": false },
        { "event": "purchase", "min_revenue_cents": 99, "fine_value": 30, "lock": false },
        { "event": "purchase", "min_revenue_cents": 999, "fine_value": 45, "lock": false },
        { "event": "purchase", "min_revenue_cents": 4999, "fine_value": 63, "lock": true }
      ],
      "coarse_mapping": {
        "low": { "events": ["app_open", "registration_complete"] },
        "medium": { "events": ["tutorial_complete"] },
        "high": { "events": ["purchase"] }
      }
    },
    "window_2": {
      "mode": "coarse_retention_and_monetization",
      "coarse_mapping": {
        "low": { "events": ["app_open"], "lock": false },
        "medium": { "events": ["session_milestone"], "lock": false },
        "high": { "events": ["repeat_purchase"], "lock": true }
      }
    },
    "window_3": {
      "mode": "coarse_long_tail_ltv",
      "coarse_mapping": {
        "low": { "events": ["app_open"], "lock": false },
        "medium": { "events": ["level_milestone"], "lock": false },
        "high": { "events": ["subscription_active"], "lock": true }
      }
    }
  }
}

動的SDK設定:ランタイムにおけるリモート設定の取得と評価

クライアントサイドのルール評価メカニズム

アトリビューションSDKは、アプリケーションランタイム内でローカルにコンバージョンルールを評価します:

  • イベントパスにおける同期型リモート設定フェッチの回避:アプリ内アクションは、アクティブなルールセットに対するローカルのメモリ内評価をトリガーし、アプリケーションの実行をブロックすることなく、即座にStoreKit APIを呼び出します。
  • データの最小化:ここで示すSKAdNetworkのコンバージョン更新パスでは、生イベントの入力をローカルで評価し、結果として得られるコンバージョンバリューのみをStoreKitに渡す必要があります。これ自体が、SDKによって実装される他のアナリティクスデータフローを説明したり制限したりするものではありません。

オフライン状態およびローカル永続化の処理

アプリケーションがオフラインまたはネットワーク接続が制限された状態で起動する場合:

  1. SDKは、リモート設定の取得とは独立して、ローカル永続化領域に初回起動のタイムスタンプアンカーを初期化します。
  2. SDKは永続ローカルストレージからピン留めされた設定スキーマをロードし、キャッシュされたペイロードがピン留めされたスキーマバージョンと一致していることを検証します。
  3. オフライン中にアプリ内イベントが発生した場合、SDKはキャッシュされたルールセットに対してそれらを評価し、即座にStoreKit更新APIを呼び出します。
  4. ポストバックの準備と配信はシステム管理による非同期処理のままであり、アプリ自身がポストバックをディスパッチする必要はありません。

以下のSwift実装は、細粒度値および粗粒度値の計算、ウィンドウ固有のロック状態の管理、ピン留めされたスキーマ設定の永続化を行い、StoreKitの実行が成功した場合にのみ状態の更新をコミットする、マルチウィンドウのスキーマ評価エンジンを示しています:

import Foundation
import StoreKit

// MARK: - Schema Configuration Models

struct SKANSchemaConfig: Codable {
    let schemaVersion: String
    let appId: String
    let currency: String
    let windows: SchemaWindows

    enum CodingKeys: String, CodingKey {
        case schemaVersion = "schema_version"
        case appId = "app_id"
        case currency, windows
    }
}

struct SchemaWindows: Codable {
    let window1: Window1Config
    let window2: WindowCoarseConfig
    let window3: WindowCoarseConfig

    enum CodingKeys: String, CodingKey {
        case window1 = "window_1"
        case window2 = "window_2"
        case window3 = "window_3"
    }
}

struct Window1Config: Codable {
    let mode: String
    let fineMapping: [FineRule]
    let coarseMapping: CoarseRuleGroup

    enum CodingKeys: String, CodingKey {
        case mode
        case fineMapping = "fine_mapping"
        case coarseMapping = "coarse_mapping"
    }
}

struct FineRule: Codable {
    let event: String
    let minRevenueCents: Int
    let fineValue: Int
    let lock: Bool

    enum CodingKeys: String, CodingKey {
        case event
        case minRevenueCents = "min_revenue_cents"
        case fineValue = "fine_value"
        case lock
    }
}

struct WindowCoarseConfig: Codable {
    let mode: String
    let coarseMapping: [String: CoarseRule]

    enum CodingKeys: String, CodingKey {
        case mode
        case coarseMapping = "coarse_mapping"
    }
}

struct CoarseRuleGroup: Codable {
    let low: CoarseRule
    let medium: CoarseRule
    let high: CoarseRule
}

struct CoarseRule: Codable {
    let events: [String]?
    let lock: Bool?
}

// MARK: - Multi-Window SKAN 4.0 Schema Engine

final class SKANSchemaEngine {

    static let shared = SKANSchemaEngine()
    private init() {}

    private var activeSchema: SKANSchemaConfig?
    private var firstLaunchDate: Date?
    private var lockedWindows = Set<Int>()
    private var lastRecordedFineValue: Int = 0
    private var pinnedSchemaVersion: String?

    /// Initializes the first-launch timestamp anchor independently of remote configuration fetches
    func initializeLifecycleAnchor() {
        let defaults = UserDefaults.standard
        if let storedLaunch = defaults.object(forKey: "skan_first_launch_date") as? Date {
            self.firstLaunchDate = storedLaunch
        } else {
            let now = Date()
            self.firstLaunchDate = now
            defaults.set(now, forKey: "skan_first_launch_date")
        }

        let lockedArray = defaults.array(forKey: "skan_locked_windows") as? [Int] ?? []
        self.lockedWindows = Set(lockedArray)
        self.lastRecordedFineValue = defaults.integer(forKey: "skan_last_fine_value")
        self.pinnedSchemaVersion = defaults.string(forKey: "skan_pinned_schema_version")

        // Restore previously cached schema payload if it matches the pinned version
        if let pinnedVersion = self.pinnedSchemaVersion,
           let cachedData = defaults.data(forKey: "skan_cached_schema_payload"),
           let cachedSchema = try? JSONDecoder().decode(SKANSchemaConfig.self, from: cachedData),
           cachedSchema.schemaVersion == pinnedVersion {
            self.activeSchema = cachedSchema
        }
    }

    /// Loads active schema, persisting the pinned payload to maintain consistency across the 35-day lifecycle
    func configure(schema: SKANSchemaConfig) {
        let defaults = UserDefaults.standard
        if let pinned = pinnedSchemaVersion {
            // If already pinned, accept only schemas matching the pinned version
            if pinned == schema.schemaVersion {
                self.activeSchema = schema
                if let data = try? JSONEncoder().encode(schema) {
                    defaults.set(data, forKey: "skan_cached_schema_payload")
                }
            }
        } else {
            // Pin the initial schema version for this lifecycle
            self.activeSchema = schema
            self.pinnedSchemaVersion = schema.schemaVersion
            defaults.set(schema.schemaVersion, forKey: "skan_pinned_schema_version")
            if let data = try? JSONEncoder().encode(schema) {
                defaults.set(data, forKey: "skan_cached_schema_payload")
            }
        }
    }

    /// Determines the active conversion window based on elapsed time from first launch
    private var currentWindowIndex: Int {
        guard let firstLaunch = firstLaunchDate else { return 0 }
        let elapsedHours = Date().timeIntervalSince(firstLaunch) / 3600.0

        switch elapsedHours {
        case 0.0..<48.0:
            return 1
        case 48.0..<168.0:
            return 2
        case 168.0...840.0:
            return 3
        default:
            return 0 // Window closed (>35 days)
        }
    }

    /// Evaluates an in-app event against the active schema for the current window
    func trackEvent(name: String, revenueCents: Int = 0) {
        guard #available(iOS 16.1, *),
              let schema = activeSchema else { return }

        let window = currentWindowIndex
        guard window >= 1 && window <= 3, !lockedWindows.contains(window) else { return }

        var targetFineValue: Int?
        var targetCoarseValue: SKAdNetwork.CoarseConversionValue?
        var shouldLock = false
        var matchedRule = false

        if window == 1 {
            // Window 1: Evaluate fine-grained rules with highest-threshold precedence
            let matchingFineRules = schema.windows.window1.fineMapping
                .filter { $0.event == name && revenueCents >= $0.minRevenueCents }
                .sorted { $0.minRevenueCents < $1.minRevenueCents }

            if let highestRule = matchingFineRules.last {
                targetFineValue = highestRule.fineValue
                if highestRule.lock { shouldLock = true }
                matchedRule = true
            }

            // Window 1: Evaluate coarse-grained rules explicitly
            if schema.windows.window1.coarseMapping.high.events?.contains(name) == true {
                targetCoarseValue = .high
                matchedRule = true
            } else if schema.windows.window1.coarseMapping.medium.events?.contains(name) == true {
                targetCoarseValue = .medium
                matchedRule = true
            } else if schema.windows.window1.coarseMapping.low.events?.contains(name) == true {
                targetCoarseValue = .low
                matchedRule = true
            }
        } else {
            // Windows 2 & 3: Evaluate coarse rules only
            let coarseConfig = (window == 2) ? schema.windows.window2 : schema.windows.window3
            
            if let highRule = coarseConfig.coarseMapping["high"], highRule.events?.contains(name) == true {
                targetCoarseValue = .high
                if highRule.lock == true { shouldLock = true }
                matchedRule = true
            } else if let medRule = coarseConfig.coarseMapping["medium"], medRule.events?.contains(name) == true {
                targetCoarseValue = .medium
                if medRule.lock == true { shouldLock = true }
                matchedRule = true
            } else if let lowRule = coarseConfig.coarseMapping["low"], lowRule.events?.contains(name) == true {
                targetCoarseValue = .low
                if lowRule.lock == true { shouldLock = true }
                matchedRule = true
            }
        }

        // If no explicit rule matched for this event, do not trigger a StoreKit update
        guard matchedRule else { return }

        let fineToSubmit = targetFineValue ?? (window == 1 ? lastRecordedFineValue : 0)
        let clampedFine = max(0, min(63, fineToSubmit))
        let coarseToSubmit = targetCoarseValue ?? .low

        // Dispatch StoreKit conversion update
        // Note: StoreKit ignores the fineValue parameter after Window 1
        SKAdNetwork.updatePostbackConversionValue(
            clampedFine,
            coarseValue: coarseToSubmit,
            lockWindow: shouldLock
        ) { [weak self] error in
            guard let self = self else { return }
            if let error = error {
                print("StoreKit conversion update failed: \(error.localizedDescription)")
            } else {
                // Commit local state only after StoreKit successfully accepts the update
                DispatchQueue.main.async {
                    if window == 1 {
                        self.lastRecordedFineValue = clampedFine
                        UserDefaults.standard.set(clampedFine, forKey: "skan_last_fine_value")
                    }
                    if shouldLock {
                        self.lockedWindows.insert(window)
                        UserDefaults.standard.set(Array(self.lockedWindows), forKey: "skan_locked_windows")
                    }
                    print("SKAN 4.0 update succeeded: Window=\(window), Fine=\(clampedFine), Coarse=\(coarseToSubmit.rawValue), Locked=\(shouldLock)")
                }
            }
        }
    }
}

SKANのlockWindowのタイミングと早期ポストバックの準備

ポストバックの準備を加速するためのlockWindow実行の自動化

lockWindowパラメータの運用メカニズム

アプリが updatePostbackConversionValue(_:coarseValue:lockWindow:)lockWindow: true で呼び出すと、その更新がアクティブウィンドウにおける最後のコンバージョンバリュー更新となります。オペレーティングシステムは即座にポストバックの準備を行い、そのウィンドウの残りの期間における追加のコンバージョンバリュー更新は無視されます。

Default Window 1 (No Lock):
[First Launch] ─────────────── 48 Hours Open ───────────────► [Closes] ──► Delay (24-48h) ──► Postback 1

Locked Window 1 (Purchase at Hour 6):
[First Launch] ── 6h (Lock: true) ──► [Conversion Locked / Postback Prepared] ──► Delay (24-48h) ──► Postback 1 Sent Sooner

自動ウィンドウロッキングにおける戦略的トレードオフ

  • ポストバック配信の早期化:コンバージョンを早期に確定させることで、Appleのランダム化されたポストバック遅延をすぐに開始させることができ、広告ネットワークへより早くコンバージョンデータを届けることが可能になります。
  • ウィンドウの独立性:現在のウィンドウをロックしても、次のウィンドウの開始時間が前倒しになることはありません。ウィンドウ1がいつロックされたかに関係なく、ウィンドウ2は常にDay 3に開始されます。
  • 観測期間の短縮:ウィンドウがロックされると、システムはそのコンバージョンウィンドウの残りの期間における後続のコンバージョンバリュー更新の呼び出しを無視します。アプリ内イベントの発生自体は継続する可能性がありますが、そのウィンドウのSKAdNetworkコンバージョン状態を変更することはできなくなります。

SKANスキーマとAdAttributionKitの連携

進化するAppleのアトリビューションスタック

Appleは現在、App Storeおよび代替アプリマーケットプレイスにわたるアプリの広告キャンペーンに向けて、AdAttributionKitを推奨しています。SKAdNetworkは既存のインテグレーションや相互運用性のために引き続き関連性を持つため、動的マッピングエンジンはビジネスルール層をフレームワーク固有のコンバージョンAPIから分離しておく必要があります:

  • 値の次元の共有:両方のフレームワークが、6ビットの細粒度値(0〜63)および3段階の粗粒度値(lowmediumhigh)を評価します。
  • 異なるAPI層:SKAdNetworkは SKAdNetwork.updatePostbackConversionValue を使用し、AdAttributionKitは Postback.updateConversionValue を使用します。
  • ブリッジング動作:インテグレーションが両方のフレームワークをサポートしている場合、Appleは文書化されたSKAdNetworkからAdAttributionKitへのブリッジング動作を考慮しつつ、両方のフレームワークのコンバージョン更新APIを呼び出すことを推奨しています。

比較決定マトリクス:ハードコードされたクライアントロジックと動的設定

評価軸 ハードコードされたクライアントサイドロジック 動的スキーマ設定
スキーマ変更の速度 App Storeの審査が必要(数日から数週間) 新規バイナリのリリースを必要とせず、サポート対象のルール変更をリモートで更新可能
テストとイテレーションの俊敏性 高いフリクション / 高いエンジニアリング負荷 バージョンおよびコホートで切り分けられたルールによる、制御されたスキーマ検証
マルチウィンドウの調整 Swiftでの複雑で手動によるステートマシン 自動化されたライフサイクル認識型エンジン
自動ウィンドウロッキング 固定された柔軟性のないルールトリガー 動的かつイベントトリガー型のロックルール
クロスフレームワークの同等性 フレームワーク間で断片化したコード 統一されたクラウド設定マトリクス

よくある質問(FAQ)

異なるコンバージョンバリューにマッピングされた複数のイベントをユーザーがトリガーした場合、どうなりますか?
SKAdNetwork 4.0では、Appleはウィンドウ1内のコンバージョンバリューが連続する呼び出しの間で増加または減少することを許可しています。ただし、アトリビューションスキーマ側でベンダーのデザイン規約として単調増加を強制している場合もあり、その場合、クライアントSDKは、受信したイベントが現在記録されている状態よりも高い値を生み出す場合にのみ、コンバージョンバリューを更新します。
アプリがオフラインの場合でも、自動化されたスキーマでコンバージョンバリューを更新できますか?
はい可能です。SDKが有効なキャッシュ済みスキーマを持っている場合、新しいスキーマを同期的にフェッチすることなく、イベントを評価してStoreKitを呼び出すことができます。SKAdNetworkのポストバックの準備と配信は、システム管理による非同期処理のまま行われます。
自動化されたスキーマは、グローバルユーザーの通貨換算をどのように処理しますか?
自動化されたスキーマエンジンは、収益バケットの閾値を評価する前に、デバイス上でアプリ内購入のすべての金額を標準的な基準通貨(USDセントなど)に正規化するか、事前に変換された整数値を渡します。

まとめと決定フレームワーク

SKAdNetworkのコンバージョンバリューマッピングの自動化により、グロース検証をモバイルバイナリのリリースサイクルから切り離すことができます。一元化されたアトリビューションダッシュボードから動的スキーマを配信し、SDK内でローカルに評価することで、エンジニアリングチームは収益バケットの微調整、ファネルマイルストーンの最適化、自動化されたウィンドウロックの設定を行うことができ、アプリケーションバイナリをApp Store Connectに再提出することなく、対応するコンバージョンルールの変更を反映させることが可能です。

アプリケーションレベルのディープリンクルーティングは、Appleのプライバシー保護アトリビューションフレームワークと並行して、独立した計測およびオンボーディングレイヤーとして機能させることができます。OpoInstallなどのプラットフォームは、ファーストパーティのコンテキストルーティングおよび遅延ディープリンクのためのインフラストラクチャを提供し、チームがウェブからアプリへのコンバージョンファネル全体でユーザーの意図を確実に保持できるように支援します。

プライバシーに準拠したアトリビューションおよびディープリンクパイプラインの設定についての詳細は、OpoInstallのドキュメントをご確認ください。

関連資料

  • 概念:コンバージョンバリュー・スキーマ、動的スキーママッピング、収益バケティング、ウィンドウロッキング、単調性

  • テクノロジー:Apple SKAdNetwork、Apple AdAttributionKit、StoreKitフレームワーク、OpoInstallモバイルSDK

  • 標準:IETF RFC 8259 JSON仕様

  • API:StoreKit updatePostbackConversionValue API、AdAttributionKit Postback.updateConversionValue API

公式ドキュメント

Share this article