adattributionkit

adattributionkit

熱門

使用 AdAttributionKit 在保護使用者隱私的前提下衡量廣告成效。適用於註冊廣告曝光(impressions)、處理歸因回傳(postbacks)、更新轉換值(conversion values)、實作重新互動(re-engagement)歸因、設定發布者(publisher)或廣告主(advertiser)App,或以 AdAttributionKit 替代 SKAdNetwork 進行廣告成效衡量。

967星標
49分支
更新於 2026/7/31
SKILL.md
唯讀
名稱
adattributionkit
描述

使用 AdAttributionKit 在保護使用者隱私的前提下衡量廣告成效。適用於註冊廣告曝光(impressions)、處理歸因回傳(postbacks)、更新轉換值(conversion values)、實作重新互動(re-engagement)歸因、設定發布者(publisher)或廣告主(advertiser)App,或以 AdAttributionKit 替代 SKAdNetwork 進行廣告成效衡量。

AdAttributionKit

適用於 iOS 17.4+ 的隱私保護型廣告歸因架構。AdAttributionKit 讓廣告網路可在不洩漏使用者層級資料的情況下衡量轉換成效(安裝與重新互動)。它支援 App Store 及替代應用程式市場,並可與 SKAdNetwork 相互搭配運作。

歸因流程中共有三種角色:廣告網路(簽署曝光、接收回傳)、發布者 App(展示廣告)以及被廣告的 App(即被推廣的目標 App)。

Contents

Overview and Privacy Model

AdAttributionKit 透過以下幾種機制保護使用者隱私:

  • 受眾匿名等級(Crowd anonymity tiers)-- 裝置會根據廣告相關的受眾規模限制回傳資料的精細度,等級從 Tier 0(最少資料)到 Tier 3(包含發布者 ID 及國家代碼等最多資料)。
  • 延遲回傳(Time-delayed postbacks)-- 回傳資料會在轉換視窗關閉後的 24-48 小時發送(第一個視窗),或 24-144 小時發送(第二/第三個視窗)。
  • 不含使用者層級識別碼(No user-level identifiers)-- 回傳內容僅包含彙整後的來源識別碼與轉換值,不會包含裝置 ID 或使用者 ID。
  • 階層式來源識別碼(Hierarchical source identifiers)-- 包含 2 位、3 位或 4 位數的來源 ID,具體回傳的位數取決於受眾匿名等級。

在進行遷移與互操作性審查時,請明確說明系統會同時評估 AdAttributionKit 和 SKAdNetwork 的曝光;每一次轉換僅由一個曝光勝出,點擊歸因(click-through)優先於瀏覽歸因(view-through),若同為點擊歸因,則以最新發生的曝光勝出,最後才降級參考最新的瀏覽歸因曝光。

Publisher App Setup

發布者 App 會展示來自已註冊廣告網路的廣告。請將各廣告網路的 ID 新增至 App 的 Info.plist 中,以便其曝光符合安裝驗證資格。

新增廣告網路識別碼

<key>AdNetworkIdentifiers</key>
<array>
    <string>example123.adattributionkit</string>
    <string>another456.adattributionkit</string>
</array>

廣告網路 ID 必須全為小寫。系統亦接受 SKAdNetwork ID(以 .skadnetwork 結尾)-- 這兩個架構共享 ID。

展示 UIEventAttributionView

針對點擊式的自訂渲染廣告,請在每個可點擊的廣告/控制項上方放置一個 UIEventAttributionView。它必須完整覆蓋可點擊區域,並維持在最上層,避免其他 View 在 handleTap() 成功前攔截觸控事件。

import UIKit

let attributionView = UIEventAttributionView()
attributionView.frame = adContentView.bounds
attributionView.isUserInteractionEnabled = true
adContentView.addSubview(attributionView)

Advertiser App Setup

被廣告的 App 指的是使用者在看到廣告後安裝或重新互動的 App。它必須至少呼叫一次轉換值更新,以開啟回傳轉換視窗。

訂閱接收勝出回傳副本

在 Info.plist 頂層的 AdAttributionKit 字典中新增 AttributionCopyEndpoint,如此裝置便會將勝出的回傳副本傳送至您的伺服器:

<key>AdAttributionKit</key>
<dict>
    <key>AttributionCopyEndpoint</key>
    <string>https://example.com</string>
</dict>

系統會從 URL 中的可註冊網域衍生出標準端點(Well-known endpoint),並忽略子網域:

https://example.com/.well-known/appattribution/report-attribution/

請將伺服器設定為接收該路徑下的 HTTPS POST 請求。該網域必須具備有效的 SSL 憑證。

訂閱接收重新互動回傳副本

在同一個 AdAttributionKit 字典中新增第二個 Key,即可同時接收勝出的重新互動回傳副本:

<key>AdAttributionKit</key>
<dict>
    <key>AttributionCopyEndpoint</key>
    <string>https://example.com</string>
    <key>OptInForReengagementPostbackCopies</key>
    <true/>
</dict>

首次啟動時更新轉換值

在首次啟動後盡早呼叫轉換值更新,以開啟轉換視窗:

import AdAttributionKit

func applicationDidFinishLaunching() async {
    do {
        try await Postback.updateConversionValue(0, lockPostback: false)
    } catch {
        print("Failed to set initial conversion value: \(error)")
    }
}

Impressions

廣告網路使用 JWS (JSON Web Signature) 建立簽署曝光。發布者 App 則使用 AppImpression 來註冊並處理這些曝光。

從 JWS 建立曝光

import AdAttributionKit

let impression = try await AppImpression(compactJWS: signedJWSString)

JWS 包含廣告網路 ID、被廣告項目 ID、發布者項目 ID、來源識別碼、時間戳記,以及可選的重新互動資格標記。詳情請參閱 references/adattributionkit-patterns.md 了解 JWS 生成細節。

檢查裝置支援狀態

guard AppImpression.isSupported else {
    // 降級改用其他廣告展示方式
    return
}

瀏覽歸因曝光

當廣告內容已展示並被關閉時,記錄一次瀏覽曝光:

func handleAdViewed(impression: AppImpression) async {
    do {
        try await impression.handleView()
    } catch {
        print("Failed to record view-through impression: \(error)")
    }
}

針對長時間顯示的廣告瀏覽,可使用 beginView()endView() 來追蹤瀏覽時長:

try await impression.beginView()
// ... 廣告維持可見狀態 ...
try await impression.endView()

點擊歸因曝光

在建立 AppImpression 的 15 分鐘內,呼叫 handleTap() 來回應廣告點擊;若逾時,請重新請求新的曝光。若尚未安裝被廣告的 App,系統會開啟其 App Store 或替代市場頁面;若已安裝,系統則會直接啟動該 App。

func handleAdTapped(impression: AppImpression) async {
    do {
        try await impression.handleTap()
    } catch {
        print("Failed to record click-through impression: \(error)")
    }
}

廣告上方必須覆蓋 UIEventAttributionViewhandleTap() 才能成功執行。

StoreKit 渲染的廣告

將曝光傳遞給 StoreKit overlay 或產品視圖控制器 API。StoreKit 會在廣告展示滿 2 秒後自動記錄瀏覽歸因曝光,並在點擊時自動記錄點擊歸因曝光。

import StoreKit

let config = SKOverlay.AppConfiguration(appIdentifier: "1234567890",
                                         position: .bottom)
config.appImpression = impression

Postbacks

回傳是裝置在發生轉換事件後,傳送給廣告網路(以及可選的被廣告 App 開發者)的歸因報告。

轉換視窗

勝出的歸因可在多個轉換視窗中產生多個回傳;較低的資料等級和未勝出的歸因揭露的資料較少。請載入 references/adattributionkit-patterns.md 查看當前的視窗與延遲矩陣。

事件的時間視窗

歸因資格視窗與轉換/回傳視窗是不同的概念。請根據最新文件與參考資料,設定並驗證瀏覽歸因、點擊歸因、安裝更新及重新互動的限制;切勿混淆這兩個概念。

提早鎖定轉換值

在視窗結束前鎖定回傳以定案轉換值,即可更早收到回傳:

try await Postback.updateConversionValue(
    42,
    coarseConversionValue: .high,
    lockPostback: true
)

鎖定後,系統在該轉換視窗內將忽略後續的更新。

各等級的回傳資料

揭露的資訊量會隨著系統分配的資料等級增加。程式碼與分析系統必須能容忍缺少的來源位數、粗略/精細轉換值、發布者項目 ID 以及國家代碼。詳細的等級矩陣由參考資料管理。

Conversion Values

精細轉換值

精細值為 0...63(6 bits)的整數。它們僅在第一個回傳中提供,且僅限於 Tier 2 或更高的等級:

try await Postback.updateConversionValue(
    35,
    coarseConversionValue: .medium,
    lockPostback: false
)

粗略轉換值

適用於較低等級以及第二/第三個回傳的三種層級:

// CoarseConversionValue cases: .low, .medium, .high
try await Postback.updateConversionValue(
    10,
    coarseConversionValue: .high,
    lockPostback: false
)

依轉換類型更新(iOS 18+)

分開安裝回傳與重新互動回傳的轉換值。在伺服器 JSON 中,使用帶連字號的 "conversion-type": "re-engagement";而在 Swift API 中,則使用不帶連字號的 .reengagement

let installUpdate = PostbackUpdate(
    fineConversionValue: 20,
    lockPostback: false,
    conversionTypes: [.install]
)
try await Postback.updateConversionValue(installUpdate)

let reengagementUpdate = PostbackUpdate(
    fineConversionValue: 12,
    lockPostback: false,
    conversionTypes: [.reengagement]
)
try await Postback.updateConversionValue(reengagementUpdate)

轉換標籤(iOS 18.4+)

當存在重疊的轉換視窗時,使用轉換標籤選擇性地更新特定的回傳:

let update = PostbackUpdate(
    fineConversionValue: 15,
    lockPostback: false,
    conversionTag: savedConversionTag,
    conversionTypes: [.reengagement]
)
try await Postback.updateConversionValue(update)

系統會透過重新互動 URL 的 AdAttributionKitReengagementOpen 查詢參數提供轉換標籤。

Re-engagement

重新互動用於追蹤已安裝被廣告 App 的使用者,透過點擊廣告重新開啟該 App 的行為。

將曝光標記為具備重新互動資格

在生成曝光時,將 JWS Payload 中的 eligible-for-re-engagement 設定為 true

使用 URL 處理重新互動點擊

傳遞一個 Universal Link,系統會在被廣告的 App 中開啟該連結:

let reengagementURL = URL(string: "https://example.com/promo/summer")!
try await impression.handleTap(reengagementURL: reengagementURL)

系統會在 URL 附加 AdAttributionKitReengagementOpen 作為查詢參數。被廣告的 App 可檢查此參數以偵測是否由 AdAttributionKit 觸發開啟:

func handleUniversalLink(_ url: URL) {
    let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
    let isReengagement = components?.queryItems?.contains(where: {
        $0.name == Postback.reengagementOpenURLParameter
    }) ?? false

    if isReengagement {
        // AdAttributionKit 透過重新互動廣告開啟了此 App
    }
}

重新互動限制

  • 僅點擊互動會建立重新互動回傳(瀏覽互動不會)。
  • 裝置會限制每月單一 App 及每年單一裝置的重新互動次數上限。
  • 即便系統未建立回傳,URL 上也永遠會存在 AdAttributionKitReengagementOpen 參數。

Common Mistakes

常見錯誤 修正方式
首次啟動時從未更新轉換值 在預期的視窗結束前呼叫標準的首次啟動更新。
廣告網路 ID 包含大寫字元 使用完全小寫的網路識別碼。
handleTap() 使用了過期的曝光或缺少當前歸因 View 的點擊 在廣告上方覆蓋 UIEventAttributionView,保持曝光最新狀態,並從通過驗證的點擊流程中呼叫。
點擊錯誤