概述
本指南介绍在共享 S2S 机制之上叠加的移动端专属归因信号:Apple Search Ads、Google Play 和 Meta 安装引荐来源、卸载追踪以及 iOS 安装收据。它适用于以 server-to-server 方式上报会话和事件的 iOS 和 Android 应用集成。
这些功能假设您已经建立了共享的 S2S 请求流程。有关它们所依赖的端点、身份验证和通用参数,请从基础知识中心和两个端点参考开始。
开始之前: 这些功能构建于共享的 S2S 请求流程之上。有关端点和通用参数,请参阅 S2S 基础知识中心 ;有关 SESSION 端点参考 ;以及 EVENT 端点参考 。
Apple Search Ads 归因
iOS Search Ads 集成
Apple Search Ads 是一种自归因网络 (SAN),需要通过 Apple 框架进行平台专属的归因实现。
框架支持:
- iOS 14.2 及以下: iAd 框架
- iOS 14.3 及以上: AdServices 框架 (推荐)
双重实现: 在 iAd 被弃用之前,请同时实现 iAd 和 AdServices 框架。Singular 在归因和报告中会优先使用 AdServices 信号而非 iAd 信号。
完整指南: Apple Search Ads 集成文档
iAd 框架实现
针对 iOS 14.2 及以下版本,通过 iAd 框架检索并发送 Apple Search Ads 归因数据。
第 1 步:检索归因数据
#import <iAd/iAd.h>
Class ADClientClass = NSClassFromString(@"ADClient");
if (ADClientClass) {
id sharedClient = [ADClientClass performSelector:@selector(sharedClient)];
if ([sharedClient respondsToSelector:@selector(requestAttributionDetailsWithBlock:)]) {
[sharedClient requestAttributionDetailsWithBlock:^(NSDictionary *attributionDetails, NSError *error) {
if (attributionDetails && attributionDetails.count > 0) {
// REPORT attributionDetails FROM YOUR APP TO YOUR SERVER
}
}];
}
}
延迟处理: 点击 Search Ads 的用户可能会立即下载并打开应用。请通过以下方式防止归因时序问题:
- 在检索归因数据之前设置几秒钟的延迟
- 如果响应为 False 或返回错误码 (0、2、3),则实现重试逻辑。在 2 秒后重试
第 2 步:发送至 Singular
通过
EVENT 端点
上报保留名称为
__iAd_Attribution__
的事件,
并将归因 JSON 作为
e
参数传递。
时序要求:
-
iOS 13+:在安装/重装后的首个会话之后立即发送
__iAd_Attribution__事件。否则 Apple Search Ads 数据将不会用于归因 -
iOS 14+:归因响应仅在
特定条件下
可用,如果 ATT 状态为
ATTrackingManager.AuthorizationStatus.denied则不可用
AdServices 框架实现
针对 iOS 14.3 及以上版本,通过 AdServices 框架检索并发送归因令牌。
第 1 步:检索归因令牌
#import <AdServices/AdServices.h>
NSError *error = nil;
Class AAAttributionClass = NSClassFromString(@"AAAttribution");
if (AAAttributionClass) {
NSString *attributionToken = [AAAttributionClass attributionTokenWithError:&error];
if (!error && attributionToken) {
// Handle attributionToken
}
}
令牌特性:
- 在设备上生成
-
缓存 5 分钟——如果调用
attributionToken(),则会在过期后生成新令牌 - 有效期为 24 小时
第 2 步:发送至 Singular
对令牌进行 URL 编码,并在每次安装和重装后的首个会话上,将其作为
attribution_token
参数附加到
SESSION 端点
。
Google Play 安装引荐来源
Android 安装归因
Google Play 安装引荐来源提供最准确的 Android 安装归因,其中包含用户在到达 Play Store 之前的来源信息。
更多信息: Google 安装引荐来源文档
实现步骤:
- 在首次打开应用时,使用 Play Install Referrer API 检索安装引荐来源
-
通过
SESSION 端点
上报会话,其中包含带有必需属性的
install_refJSON 参数
install_ref 属性:
| 参数 | 详情 |
|---|---|
referrer
|
来自 Play Install Referrer API 的引荐来源值(JSON 对象——编码为字符串) |
referrer_source
|
指定为 "service" |
clickTimestampSeconds
|
来自 API 的点击时间戳(例如 "1550420123") |
installBeginTimestampSeconds
|
来自 API 的安装开始时间 |
current_device_time
|
当前设备时间(毫秒,例如 "1550420454906") |
Meta 安装引荐来源
Facebook 归因增强
自 2025 年 6 月 18 日起: Meta 的 高级移动测量 (AMM) 消除了实现 Meta 安装引荐来源的需求。如果已启用 AMM,则不推荐使用。
Meta Referrer 是 Android 专属的测量解决方案,结合了 Google Play 安装引荐来源和 Meta 安装引荐来源技术,为应用安装提供精细的用户级归因数据。
了解更多: Meta Referrer 常见问题
实现步骤:
- 在首次打开应用时,根据 Meta 的文档 检索 Meta 安装引荐来源
-
通过
SESSION 端点
上报会话,其中包含带有必需属性的
meta_refJSON 参数
meta_ref 属性:
| 参数 | 详情 |
|---|---|
is_ct
|
来自 Meta 安装引荐来源的 is_ct(0 或 1) |
install_referrer
|
来自 Meta 安装引荐来源的 install_referrer |
actual_timestamp
|
来自 Meta 安装引荐来源的 actual_timestamp(例如 1693978124) |
卸载追踪
静默推送通知设置
通过在每次会话通知中发送推送令牌,使用设备静默推送通知来追踪卸载。
设置要求:
- 遵循平台专属的卸载追踪设置:
-
将平台专属的令牌附加到 SESSION 请求:
-
iOS:
apns_token(APNs 设备令牌) -
Android:
fcm(FCM 设备令牌)
-
iOS:
iOS 安装收据
收据验证
在上报 iOS 会话时,将 iOS 安装收据传入
install_receipt
参数。
import Foundation
import StoreKit
class ReceiptManager {
static func getInstallReceipt() -> String? {
if #available(iOS 18.0, *) {
let semaphore = DispatchSemaphore(value: 0)
var result: String?
Task {
do {
let transaction = try await AppTransaction.shared
result = transaction.jwsRepresentation
semaphore.signal()
} catch {
debugPrint("Failed to get app transaction: \(error.localizedDescription)")
semaphore.signal()
}
}
semaphore.wait()
return result
} else {
guard let receiptURL = Bundle.main.appStoreReceiptURL else {
debugPrint("Receipt URL not found")
return nil
}
do {
let receiptData = try Data(contentsOf: receiptURL, options: .uncached)
return receiptData.base64EncodedString(options: [])
} catch {
debugPrint("Failed to read receipt: \(error.localizedDescription)")
return nil
}
}
}
}