使用 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)")
}
}
廣告上方必須覆蓋 UIEventAttributionView,handleTap() 才能成功執行。
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,保持曝光最新狀態,並從通過驗證的點擊流程中呼叫。 |
| 點擊錯誤 |






