Highlight
SKAdNetwork 4.0 将 Campaign ID 扩展为层级 Source Identifier,引入粗细两级转化值、三轮 postback、Web 广告归因和 StoreKitTest 测试能力,让广告主在 crowd anonymity 约束下获得更多安装归因信号。
核心内容
做广告归因有一个长期矛盾:广告主需要知道广告是否带来安装和后续行为,用户不希望自己的行为被跨 App 或跨网站追踪。SKAdNetwork 的位置就在这里。它让广告网络、publisher app 和 advertiser app 通过签名 impression、首次启动信号、conversion value 更新和 postback 完成安装归因,同时把用户隐私保护放在协议里(00:36)。
SKAdNetwork 4.0 的核心变化,是在不突破隐私边界的前提下给广告主更多信号。Apple 用 crowd anonymity 描述这个边界:安装量低时,postback 返回更少字段;安装量升高后,用户混入更大的群体,系统才返回更多细节(03:38)。
这套规则影响每一个新字段。Source Identifier 的位数、conversion value 的粒度、postback 的次数,都会受 crowd anonymity 约束。开发者要做的事情也变了:字段不能随便编码,服务器不能只解析旧格式,测试不能等线上广告跑起来才发现签名或 postback 有问题。
从单一 Campaign ID 到层级 Source Identifier
旧版 SKAdNetwork 的 campaign identifier 是 2 位字段。SKAdNetwork 4.0 把它扩展到 4 位,并改名为 Source Identifier。Apple 建议把它当成 2 位、3 位、4 位三层结构,而不是一个普通整数(04:41)。
这个设计适合归因钻取。前 2 位可以代表广告活动,第 3 位可以代表分桶后的用户位置,第 4 位可以代表屏幕上的广告位置。也可以把它设计成 treatment、时间段、广告尺寸。关键点是:低匿名等级可能只返回 2 位,高匿名等级才返回完整 4 位。
从一次 postback 到三次 postback
旧模型只有一个 postback。Food Truck 示例里,用户启动 App、拿起第一批甜甜圈后,postback 时间到了;用户后来完成配送,这个后续行为就无法再归因(10:18)。
SKAdNetwork 4.0 改成三个固定时间窗口,对应三个 postback。第一轮仍然能携带 fine conversion value;后两轮可以携带 coarse conversion value。这样,开发者能把安装后的短期行为和更晚发生的 re-engagement 分开记录(11:21)。
Web 广告也进入 SKAdNetwork 流程
过去的典型流程发生在 publisher app:广告点击打开 App Store 产品页,安装后由 SKAdNetwork 发 postback。SKAdNetwork 4.0 把同样的隐私保护归因扩展到网页广告。用户在 Safari 点广告链接后,App Store 会从广告网络服务器获取签名 impression,再走后续安装归因流程(12:53)。
Web 链接里有两个关键字段:attributionDestination 告诉 Apple 去哪里获取签名 impression,attributionSourceNonce 帮助广告网络定位要返回的那一份签名 impression(13:47)。
详细内容
1. Source Identifier 要按匿名等级设计
(04:41)SKAdNetwork 4.0 把 2 位 campaign identifier 扩展为 4 位 Source Identifier。返回结果随 crowd anonymity 变化:低等级返回 2 位,中等级返回 3 位,高等级返回完整 4 位(07:04)。
可以把 Source Identifier 当成嵌套信息来设计。以 transcript 中的 5739 为例,返回粒度随 crowd anonymity 提升而增加:
| Crowd anonymity | postback 中可能返回的内容 | 设计含义 |
|---|---|---|
| Low | 2-digit component | 最少细节,只放最关键、最低风险的业务分类 |
| Medium | 3-digit component | 在 2 位基础上增加一层分桶信息 |
| High | full 4-digit source identifier | 返回完整 4 位,可包含最细的实验、位置或广告展示信息 |
关键点:
- Source Identifier 是 SKAdNetwork 4.0 新的 4 位字段,替代过去的 2 位 campaign identifier。
5739应该被理解为嵌套业务维度的编码结果,不要把完整 4 位误标成单个“广告位”或“位置”字段。- transcript 说明
SKAdImpression有新的sourceIdentifier属性;如果使用 dictionary 配置 impression,也要填写 Source Identifier 字段,具体 key 以 Apple 文档和当前 SDK 为准。 - 服务端和客户端必须共享同一套编码表,否则 postback 里的数字无法还原业务含义。
- 编码表要覆盖 2 位、3 位、4 位三种返回情况;不要把最重要的信息只放在第 4 位,因为低匿名等级下它不会返回。
2. Conversion value 分成 fine 和 coarse
(06:08)旧版 conversion value 是 6 bit。SKAdNetwork 4.0 引入两种值:fine-grained conversion value 仍然是原来的细粒度值;coarse-grained conversion value 只有 low、medium、high 三档。
Apple 给出的例子是 high 42:high 是 coarse value,42 是 fine value。coarse value 需要的安装量更低,因此 App 能更早拿到粗粒度结果;同一次 postback 只会返回其中一种 conversion value(06:34)。
// 概念示例:用 fine + coarse 两层值描述一次用户行为
let fineValue = 42
let coarseValue = "high"
SKAdNetwork.updatePostbackConversionValue(
fineValue,
coarseValue: coarseValue
) { error in
// transcript 建议在 completion handler 中执行后续任务
}
关键点:
updatePostbackConversionValue是 transcript 中提到的新方法名。fineValue对应旧版 6 bit conversion value。coarseValue对应 low、medium、high 三档值。- completion handler 应用于更新完成后的后续任务,这是 session 中明确给出的建议(08:33)。
- 真实项目应使用当前 SDK 的正式类型和签名,不能直接把这个概念片段复制进生产代码。
设计 coarse value 时,不要把它当成 fine value 的简单截断。三档值只有很少信息量,适合表达“还没激活 / 已完成核心动作 / 高价值用户”这类粗分类。
3. 三轮 postback 要服务不同时间窗口
(09:57)单一 postback 只能覆盖一个时间窗口。SKAdNetwork 4.0 的三个 postback 让开发者能记录安装后的不同阶段:启动、首次核心行为、后续 re-engagement。
// 概念示例:把不同阶段映射到不同 postback 窗口
func userDidLaunchApp() {
updateConversion(window: 1, coarse: "low", fine: 5)
}
func userDidCompleteFirstDelivery() {
updateConversion(window: 2, coarse: "medium", fine: nil)
}
func userDidCreateNewRecipe() {
updateConversion(window: 3, coarse: "high", fine: nil)
}
关键点:
window: 1对应第一轮 postback,它可以获得 fine conversion value。window: 2和window: 3对应额外 postback,session 说明它们可以携带 coarse conversion value。fine: nil表示后两轮不依赖细粒度值。- 这个片段表达业务映射方式,
updateConversion不是 Apple API。
服务器也要按三轮 postback 存储数据。不要只保留“最后一次归因结果”。第一轮适合衡量安装后的早期质量,第二轮和第三轮适合衡量更晚发生的价值行为。
4. Web 广告归因需要能返回签名 impression
(13:47)Web 广告链接的 href 指向 App Store 产品页。attributionDestination 告诉 Apple 到哪个域名取签名 impression。attributionSourceNonce 帮助广告网络找到对应的 impression。
<!-- 概念示例:Web 广告链接包含 App Store 目标和归因字段 -->
<a
href="https://apps.apple.com/app/id123456789"
attributionDestination="https://ad-network.example"
attributionSourceNonce="nonce-from-ad-network">
Download the app
</a>
关键点:
href是被广告推广的 App Store 链接。attributionDestination是 Apple 获取签名 impression 的位置。attributionSourceNonce用来让广告网络定位原始广告 impression。- session 说明这类链接可用于 first-party site,也可用于 embedded cross-site iframe(14:11)。
Apple 会从 attributionDestination 提取 eTLD+1,再加上 fixed protocol、well-known qualifier 和固定 path components,构造 HTTP POST URL。POST body 是 JSON,并包含原始链接里的 source_nonce(14:22)。
{
"source_nonce": "nonce-from-ad-network"
}
关键点:
source_nonce与广告链接中的 nonce 对应。- 广告网络用它查找并返回签名 impression。
- 返回的 signed impression 会包含 source domain,它是 Web 归因流程里对应 source app ID 的字段。
- postback server 要能解析新的可选 source domain 字段(15:43)。
5. StoreKitTest 可以验证 impression 和 postback
(16:28)Apple 在 Xcode 13.3 中提供 SKAdNetwork testability changes,放在 StoreKitTest 的 unit testing framework 里。它解决两个常见摩擦点:impression 的签名和配置,以及 postback 的接收和验证。
验证 impression 的流程是:创建并配置 SKAdImpression,提供生成签名所用私钥对应的 public key,然后调用 SKAdTestSession 的 validate 方法。配置错误或签名无效都会抛错(17:19)。
// 概念示例:验证 SKAdImpression 的配置和签名
let impression = SKAdImpression()
let publicKey = loadPublicKeyForTesting()
try skAdTestSession.validate(impression, publicKey: publicKey)
关键点:
SKAdImpression是被测试的广告 impression。publicKey对应签名私钥,session 明确要求提供它。validate来自SKAdTestSession。- 这个测试能在签名或 impression 配置错误时提前失败。
测试 postback 分两步。先创建 SKAdTestPostback,配置要发送的值和 postback URL,再通过 setPostbacks 加到 SKAdTestSession。随后调用 flushPostbacks,测试 postback 会被发送到指定的本地或远程服务器(17:49)。
// 概念示例:把测试 postback 送到指定服务器
let postback = SKAdTestPostback()
postback.url = URL(string: "https://example.test/skadnetwork/postback")!
skAdTestSession.setPostbacks([postback])
skAdTestSession.flushPostbacks()
关键点:
SKAdTestPostback表示要模拟发送的 postback。postback.url是接收服务器地址,可以是远程服务器,也可以是本地服务器。setPostbacks把测试 postback 加入 session。flushPostbacks触发发送,session 说明它会经由网络发到指定服务器。
核心启发
1. 做一个 Source Identifier 编码表检查器
- 做什么:把 4 位 Source Identifier 拆成 2 位、3 位、4 位三层含义,检查低匿名等级下是否仍能返回关键业务信息。
- 为什么值得做:SKAdNetwork 4.0 会按 crowd anonymity 返回不同位数;错误编码会让低量级广告完全失去可分析信号。
- 怎么开始:从 campaign、位置分桶、广告位三个维度建表,再为每个维度写反解逻辑。
2. 做一套 coarse conversion value 映射后台
- 做什么:为 low、medium、high 三档定义独立含义,并把它们映射到安装后的关键行为阶段。
- 为什么值得做:coarse value 比 fine value 更早返回,适合新广告活动或安装量较低的场景。
- 怎么开始:把事件分成“启动”、“完成核心动作”、“高价值行为”三类,再将它们写入 conversion 更新策略。
3. 做三轮 postback 的归因看板
- 做什么:按第一轮、第二轮、第三轮分别展示安装质量、后续行为和 re-engagement。
- 为什么值得做:SKAdNetwork 4.0 不再只给一次 postback,后两轮能补上旧模型丢失的长期行为。
- 怎么开始:服务器表结构增加 postback sequence 或窗口字段,查询层按窗口聚合转化事件。
4. 做 Web 广告签名 impression 服务
- 做什么:根据
source_nonce返回对应的 signed impression,并记录 source domain。 - 为什么值得做:Web 广告进入 SKAdNetwork 后,广告网络需要能在 Apple 构造的 URL 上响应 HTTP POST。
- 怎么开始:先实现 nonce 到 impression 的查找接口,再让 postback 解析逻辑兼容可选 source domain。
5. 做本地 postback 验证环境
- 做什么:用
SKAdTestSession和SKAdTestPostback把测试 postback 发到本地服务器,验证接收、解析和落库。 - 为什么值得做:签名配置和 postback 接收是 session 中明确提到的摩擦点,单元测试能把问题提前暴露。
- 怎么开始:在测试里配置 postback URL 指向本地服务,调用
setPostbacks和flushPostbacks,断言服务器收到预期字段。
关联 Session
- Discover Benchmarks in App Analytics — 继续看 App Store App Analytics 如何用隐私保护方式比较同类 App 表现。
- What’s new in App Store Connect — 了解 App Store Connect 和 API 更新,便于把归因、分析和上架流程放在同一套运营工具里。
- What’s new in StoreKit testing — 学习 StoreKit testing 的其他测试能力,与本 session 的 SKAdNetwork testability 配套使用。
- Explore App Tracking Transparency — 补齐广告、归因和用户隐私授权之间的政策与实现边界。
评论
GitHub Issues · utterances