在无法访问广告标识符的情况下,如何处理移动应用归因? 您完全可以在没有 GAID 或 IDFA 的情况下进行应用安装归因,但底层架构需要做出调整:现代数据管道不再依赖持久的广告标识符,而是将平台中介归因框架、Google Play Install Referrer、第一方上下文参数路由以及服务端验证有机结合。
广告标识符(Advertising ID)是由移动平台提供的一个可重置的软件标识符,主要用于广告和效果衡量场景。在 Android 上,这是通过 Google Play 服务提供的广告 ID;而在 Apple 平台上,IDFA 的访问则受“应用跟踪透明度(ATT)”框架的严格管控。
| 术语 | 定义 |
|---|---|
| 广告标识符 | 用于移动广告效果衡量的可重置软件标识符。 |
| GAID | 通过 Android 设备上的 Google Play 服务进行管理的谷歌广告 ID。 |
| IDFA | iOS 上受应用跟踪透明度(ATT)框架管控的苹果广告商标识符。 |
| 上下文参数路由 | 在用户主动发起的 web-to-app 转化链路中,通过第一方方式传输营销活动或引荐上下文。 |
极简摘要:无 ID 移动应用归因概览
谷歌广告 ID 无法由单一的即插即用标识符直接替代。相反,归因工作被拆解为不同的、专为特定目的构建的基础组件:
-
付费广告活动报告(Android):对于通过 Play 商店分发的安装,使用 Google Play Install Referrer API 来检索商店中介的营销活动参数。
-
付费广告活动报告(iOS):使用 Apple AdAttributionKit 和 SKAdNetwork 获取平台签名、保护隐私的回传数据。
-
Web-to-App 引导与引荐:使用第一方安装上下文恢复层(例如 OpoInstall)在首次启动时恢复优惠码、房间 ID 和邀请者令牌。
-
跨应用重定向(Retargeting):需要获得授权的平台支持标识符或衡量机制,并严格遵守适用的平台政策、用户控制和隐私授权要求。
架构决策矩阵:选择合适的归因基础组件
为了确定适合您应用的具体技术机制,请将您的特定业务需求与平台功能进行评估对比:
| 功能需求 | 核心技术组件 | GAID / IDFA 依赖性 | 归因输出类型 |
|---|---|---|---|
| Play 商店广告活动衡量 | Google Play Install Referrer API | 无(通过商店 URL 运行) | 商店提供的安装上下文 |
| iOS 广告网络衡量 | Apple AdAttributionKit / SKAdNetwork | 无(平台中介) | 保护隐私的平台回传数据 |
| 应用内引导与延迟深度链接(Deferred Deep Linking) | 第一方上下文参数路由 | 无(第一方上下文) | 首次启动时的实时自定义负载 |
| 用户间引荐绑定 | 动态引荐令牌 | 无(会话/账户级别) | 直接的邀请者-受邀者账户配对 |
| 跨应用用户重定向 | 平台支持的广告机制 | 不一定;取决于具体机制与政策 | 用户级或群组级标识符 |
GAID 的替代方案:真正有效的方法
当工程团队寻找“GAID 替代方案”时,他们通常试图用单一工具解决多个彼此独立的运维问题。在生产环境中,依赖 GAID 的架构必须被拆解为四个独立的解决方案:
Legacy GAID Workflows
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
Paid Campaign ROI Web-to-App Routing Referral Binding
│ │ │
▼ ▼ ▼
Play Install Referrer / First-Party Context First-Party Referral
AdAttributionKit Parameter Routing Token Restoration
-
替代基于 GAID 的安装上下文检索:在适用情况下,为 Play 分发的安装使用 Google Play Install Referrer,并结合广告网络集成和平台支持的归因 API。这些框架提供安装来源上下文,而不会暴露持久的硬件或广告标识符。
-
替代用于引导和深度链接的 GAID:部署第一方安装上下文恢复层(例如 OpoInstall)。通过自有营销活动 URL 传递动态参数,而不是查询广告 ID 来关联点击日志,并在首次启动时通过客户端 SDK 恢复这些参数。
-
替代用于用户身份识别的 GAID:使用经过身份验证的第一方账户系统(如 OAuth 或内部用户 UUID)而非设备级广告密钥。
核心架构分类:不同组件提供的能力
| 衡量目标 | 底层信号 | 是否包含用户级标识符? | 是否由平台中介? |
|---|---|---|---|
| 活动级广告衡量 | Apple AdAttributionKit / SKAN | 否 | 是 |
| Play 商店安装上下文 | Google Play Install Referrer | 否 | 是 |
| 延迟深度链接引导 | 第一方上下文令牌 | 可能是账户/会话级别 | 否 |
| 用户引荐绑定 | 引荐令牌 + 账户配对 | 是(第一方账户) | 否 |
| 跨应用设备身份 | 授权广告 ID | 是 | 是 |
GAID 与 Install Referrer 以及第一方参数恢复的对比
| 归因机制 | 是否需要 GAID / IDFA? | 标识符模型 | 主要目标 |
|---|---|---|---|
| 谷歌广告 ID (GAID) | 是 | 平台广告标识符 | 跨应用广告效果衡量 |
| Google Play Install Referrer | 否 | 商店提供的安装上下文 | Play 安装广告活动归因 |
| Apple AdAttributionKit / SKAN | 否 | 保护隐私的归因信号 | 平台广告衡量 |
| 第一方参数路由 | 否 | 第一方令牌 / 账户上下文 | 深度链接与引荐绑定 |

Android 应用归因的 GAID 替代方案
在无法访问谷歌广告 ID 的 Android 设备上运行时,工程团队会根据具体的营销渠道部署相应的替代机制:
| GAID 替代方案 | 核心实现机制 | 典型应用场景 | 关键运维限制 |
|---|---|---|---|
| Google Play Install Referrer | Play Install Referrer API | Play 商店广告活动和直接下载链接 | 仅限于 Google Play 分发的安装 |
| 第一方上下文令牌 | Web JS SDK + 原生 SDK 恢复 | 用户引荐计划和 web-to-app 引导 | 严格局限于直接的第一方用户旅程 |
| 平台归因 API | Android Privacy Sandbox 归因报告 API | 聚合广告网络转化报告 | 取决于平台推送进度和接入情况 |
| 服务器到服务器 (S2S) 集成 | 广告网络回传 + 后端 API | 直接合作伙伴归因与 API 对账 | 需要针对每个网络进行直接技术对接 |
移动测量平台 (MMP) 如何在没有 GAID 的情况下处理衡量
诸如 AppsFlyer、Adjust、Singular 和 Branch 等移动测量平台 (MMP) 已对其技术架构进行了调整,以在缺少广告标识符的情况下支持衡量工作:
| 平台 / 层级 | 主要的 Android 无 ID 信号 | 主要的 iOS 无 ID 信号 | 衡量粒度 |
|---|---|---|---|
| MMP / 归因平台 | 平台归因信号、Install Referrer、网络 API、S2S 集成 | AdAttributionKit / SKAdNetwork 及网络集成 | 因平台、网络和衡量框架而异 |
| 平台原生 API | Google Play Install Referrer API | Apple AdAttributionKit 框架 | 回传和商店中介的安装数据 |
| 第一方路由层 | 上下文参数缓存、Web-to-App 参数令牌 | 瞬时上下文匹配、动态通用链接(Universal Links) | 用于引导的实时、用户级自定义 JSON 负载 |
通过将用于宏观广告网络报告的 MMP 与用于微观引导个性化的第一方上下文路由层相结合,工程团队可以建立一套互补的衡量和引导技术栈,且不会违反操作系统的隐私沙盒政策。
为什么广告标识符限制会破坏确定性移动归因
对持久广告标识符的历史依赖
十多年来,移动效果广告一直依赖由平台广告标识符驱动的确定性设备级匹配:Android 上的谷歌广告 ID (GAID) 和 iOS 上的广告商标识符 (IDFA)。在这种传统工作流程中,广告网络在广告曝光或点击时捕获用户的广告 ID。随后在应用安装并启动时,集成的归因 SDK 会查询设备操作系统以检索匹配的广告 ID。
一个简单的服务端相等性查找(
标识符置零与平台限制的机制
移动操作系统架构不断演进,在未经明确用户同意的情况下限制跨应用设备跟踪。
在 Apple 平台上,Apple 应用跟踪透明度准则要求应用通过 ATTrackingManager.requestTrackingAuthorization 请求跟踪授权。在没有授权的情况下,操作系统将扣留 IDFA。应用必须妥善处理 denied(拒绝)、restricted(受限)和 notDetermined(未决定)状态,而不能假设广告标识符可用。
在 Android 上,根据 Android 13 行为变更文档,谷歌在 Google Play 服务中引入了明确的权限控制。对于目标定位为 Android 13(API 级别 33)或更高版本的应用,开发者必须在其清单中声明 com.google.android.gms.permission.AD_ID 权限才能访问广告 ID。当省略此权限,或者当用户限制广告跟踪或删除其广告 ID 时,Google Play 服务可能会返回置零的标识符(00000000-0000-0000-0000-000000000000),或者根据设备状态和 Google Play 服务的行为指示该标识符不可用。
确定性广告归因管道的失效
当广告标识符不可用或被置零时,依赖标识符相等性的归因管道将无法再执行可靠的用户级匹配。被置零或不可用的广告标识符无法提供用于区分各个转化旅程的唯一键。
为了维持营销活动衡量和转化追踪,工程团队必须摆脱对广告 ID 的依赖。现代架构将安装归因与持久设备标识符解耦,转而依赖第一方上下文路由和平台提供的衡量框架。
在此架构中,OpoInstall 被呈现为第一方安装上下文恢复/延迟深度链接层,而不是作为 Google Play Install Referrer、AdAttributionKit、SKAdNetwork 或其他平台中介广告归因系统的通用替代品。
Android 广告 ID 权限和 Apple ATT 如何影响归因
Android 13 及更高版本上的 Google Play AD_ID 权限政策
Google Play 对广告标识符的提取实施了细颗粒度的政策管控:
-
清单声明要求:目标定位为 Android 13(API 级别 33)或更高版本的应用必须在其清单中声明
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>。如果省略,对AdvertisingIdClient.getAdvertisingIdInfo(context)的调用将返回零或指示不可用状态。 -
用户隐私控制:当用户限制广告跟踪或删除其广告 ID 时,Google Play 服务会返回零或不可用状态。Google Play 开发者政策明确禁止使用其他持久设备标识符来桥接或重建已重置的广告 ID。
-
针对敏感应用的政策例外:Google Play 政策禁止在针对儿童或受家庭政策约束的应用中声明
AD_ID权限,这要求开发者采用无 ID 衡量管道。
Apple AppTrackingTransparency 框架与授权状态
在 iOS 上,标识符访问受 ATTrackingManager.AuthorizationStatus 系统状态管控:
-
notDetermined(0):用户尚未响应 ATT 授权请求。应用不应假设 IDFA 访问可用。 -
restricted(1):设备受家长控制或设备管理配置文件限制;跟踪在系统范围内被禁用。 -
denied(2):用户在提示中明确选择了“要求应用不跟踪”,或在 iOS 隐私设置中全局禁用了跟踪请求。应用不得依赖 IDFA。 -
authorized(3):用户明确授予跨第三方应用和网站跟踪的权限,允许在遵守 Apple 平台政策的前提下访问 IDFA。
重要的架构边界声明
重要区别:从归因架构中移除 GAID 或 IDFA 并不会自动使每种替代跟踪技术都变得符合隐私安全或政策规定。根据 Apple 的应用跟踪透明度框架指南,Apple 将跟踪定义为:将从您的应用收集的用户或设备数据与第三方数据链接用于定向广告或衡量,或与数据经纪人共享数据。如果某个工程管道收集设备特征以重建持久的跨应用身份,则无论是否访问了广告标识符,它仍然受平台跟踪政策的约束。第一方参数路由必须严格限定在用户主动发起的旅程的即时引导和转化上下文中。
无 ID 归因不意味着什么
无 ID 归因并不意味着完全没有标识符的分析。应用仍可处理内部产品功能所需的账户标识符、第一方会话令牌或深度链接参数。架构的目标是消除安装匹配对持久跨应用广告标识符的依赖,而不是声称所有归因数据完全匿名。
不应混淆的三大归因问题
在构建没有广告标识符的移动归因时,工程团队必须区分三个不同的运维目标:
| 问题 | 使用的主要信号 | 工程目标 |
|---|---|---|
| 广告归因 | 平台归因 API、Google Play Install Referrer、广告网络专用衡量 | 衡量广告驱动的营销活动效果和广告花费效率 |
| 延迟深度链接 (Deferred Deep Linking) | URL 查询参数、Universal Links、App Links | 在商店安装后恢复应用内目的地上下文 |
| 引荐归因 | 第一方引荐令牌、用户账户 ID | 为产品奖励绑定邀请者和受邀者账户 |
第一方路由机制可以在不需要 GAID 或 IDFA 的情况下解决延迟深度链接和引荐归因,但不应将其视为平台中介广告归因的通用替代品。
增长团队何时应该部署第一方归因层?
建议为运行特定产品工作流程的应用部署独立的第一方归因层:
-
SaaS 与订阅应用:营销流量始于桌面端或移动网页端,并转化为需要预验证会话恢复的原生应用账户的 B2B 平台。
-
游戏应用:新玩家在首次启动时必须自动加入邀请者的比赛、公会或房间,而无需手动输入房间代码的多人或社交游戏。
-
电商平台:提供个性化欢迎折扣或将活跃购物车状态从移动网页活动直接恢复到原生结账视图的购物应用。
-
引荐与忠诚度平台:推动有机病毒式传播循环的产品,需要可靠的邀请者-受邀者令牌绑定,而无需强迫用户复制粘贴优惠券字符串。
无 ID 第一方参数路由的架构蓝图
将归因与持久设备标识符解耦
在本文中,我们使用上下文参数路由(也称为第一方延迟归因或安装上下文恢复)来描述在用户主动发起的 web-to-app 旅程中对营销活动或引荐上下文的第一方传输。
现代归因架构侧重于营销互动的交易上下文,而不是试图追踪物理设备。当潜在用户点击营销活动链接时,系统会为其交互分配一个包含营销活动元数据、渠道令牌和应用路由参数的瞬态路由负载。
此负载随用户旅程贯穿转化漏斗,允许移动应用在启动时恢复上下文意图,而无需查询系统级广告 ID。
双层归因架构
企业归因架构将直接深度链接与商店中介的安装流程分离开来:
User Marketing Interaction
│
┌────────────────┴────────────────┐
│ │
Direct App Link Store / Ad Flow
│ │
Universal Links / ┌──────┴───────┐
App Links │ │
│ Android Apple
│ Play Install Platform Ad
│ Referrer Attribution
│ │ │
└──────────────┬────────┴──────┬───────┘
│ │
Attribution / Routing Signals
│
Server-Side Validation
│
┌─────────┴─────────┐
│ │
Context Found No Signal
│ │
Route / Bind Organic /
First-Party Graceful Fallback
上下文参数路由和回退的技术机制
第一方参数传输的作用
第一方参数传输依赖于标准的网页查询解析和安全的服务器端会话缓存。开发者可以查阅 OpoInstall SDK 文档了解有关参数绑定模型的技术规范。
当实现不符合 Apple 的跟踪定义时,仅用于直接引导的第一方参数路由不一定需要 ATT;团队应根据 Apple 的最新政策评估实际的数据流和用途。
平台特定的安装归因回退
当直接深度链接被商店安装中断时,特定于平台的图元会提供结构化的归因数据:
-
Android (Google Play Install Referrer):Google Play Install Referrer API 指南公开了与 Play 商店安装相关的引荐来源网址信息,并提供点击和安装时间戳。API 文档规定了引荐数据的 90 天可用窗口期。应用应根据自身的归因和重新安装处理规则来持久化和处理该值,而不是将其视为永久安装标识符。请注意,参数必须显式通过 Google Play 传递;任意落地页查询参数不会自动填充此 API。
-
Apple 平台归因:Apple 现代的应用归因技术栈包括 Apple AdAttributionKit 框架,以及针对支持的广告工作流程与 SKAdNetwork 的互操作性。AdAttributionKit 本身不需要 ATT 授权提示;但是,同一应用中的其他数据流可能仍构成跟踪,因此需要 ATT 授权。AdAttributionKit 在 Apple 签名的广告框架内运行,并注册了符合条件的广告网络。
为什么基于剪贴板的归因不应成为主要策略
剪贴板或粘贴板传输通常应被视为一种异常的回退机制,而不是主要的归因设计。剪贴板访问会引入用户可见的隐私通知、平台限制以及跨操作系统版本的可用性不一致。在评估粘贴板存储时:
-
明确范围: 有效负载应是短命的,并限制为预期第一方流程所需的最小应用特定数据。敏感值在传输和静态存储时应得到适当保护。
-
立即清理: 应用在初始启动序列期间消费临时参数令牌后,应立即清除或覆盖它们。
-
政策合规: 仅在存在明确定义的第一方用户流且符合适用的平台政策审查的情况下,才使用粘贴板机制。
优雅回退与未归因状态
具韧性的隐私架构不会试图通过侵入性设备指纹识别来强行进行归因匹配:
-
直接应用链接 / 通用链接 (Universal Link): 当应用已安装在设备上时,即时唤醒原生应用。
-
商店中介参数传递: 在可用时通过平台 API(例如 Google Play Install Referrer)检索营销活动参数。
-
第一方参数恢复: 在狭窄的时间窗口内将新安装会话与活动的网页落地页互动进行匹配。
-
无信号(未归因): 当网络条件改变、会话过期或不存在匹配上下文时,应用安全地降级到干净的默认状态,而不会中断用户引导体验。
示例实现方案:使用 OpoInstall 进行上下文恢复
为了解这些图元在生产环境中的运作方式,请考虑一个执行两个同时获客渠道的跨平台移动游戏应用:
-
渠道 A(付费程序化广告):在外部广告网络上运行并重定向至 App Store 和 Google Play 的广告活动。
-
渠道 B(用户病毒式分享):现有玩家通过社交即时通讯应用分享自定义邀请链接(
https://game.example.com/join?room=9876&inviter=usr_432)。
*
[Channel A: Paid Ad] ──> [Store Download] ──> [Play Referrer / AdAttributionKit] ──> [Aggregated Ad ROI]
[Channel B: Invite] ──> [Web Landing] ──> [First-Party Token Restoration] ──> [Auto-Join Game Room]
当新用户通过渠道 A 安装时,应用依赖 Google Play Install Referrer API 或 Apple AdAttributionKit 向营销仪表盘报告营销活动表现。当用户通过渠道 B 安装时,第一方路由 SDK 会在首次启动时捕获动态邀请令牌,立即将新玩家加入房间 9876,而无需查询广告 ID 或触发 ATT 提示。
无 ID 移动归因中的常见生产故障案例
在部署不依赖持久广告标识符的归因架构时,工程团队经常会遇到特定的运维故障模式:
-
故障案例 1:落地页参数在重定向后丢失:如果营销活动链接通过未编码的中间 URL 缩短器进行重定向,诸如
channelCode或referrer等查询参数可能会在到达落地页脚本或应用商店目的地之前被剥离。 -
故障案例 2:重复引荐兑换和缺少幂等性锁:在生产环境中,如果移动客户端在每个
Activity.onResume或应用前台事件上调用参数恢复而不同时检查本地持久化标志,用户可能会触发重复的奖励索赔或反复的深度链接导航。 -
故障案例 3:重新安装状态管理不当:虽然 Google Play Install Referrer 保留历史引荐数据长达 90 天,但重新安装的应用可能会从先前的安装生命周期中收到陈旧的归因数据,除非客户端后端验证账户是否已完成注册。
-
故障案例 4:通过宽泛的匹配窗口被错误归类为自然安装:如果在共享网络或高用户密度的环境中将服务端会话匹配窗口配置得太宽,自然安装可能会与无关的网页点击会话发生冲突。
第一方安装上下文恢复的说明性 SDK 集成模式
客户端集成概述
第一方安装上下文恢复 SDK 可用于实现上下文参数恢复,而无需广告 ID。开发团队可以下载 OpoInstall 移动 SDK 软件包和集成资源。
SDK API 注意事项: 下面显示的初始化和检索生命周期是一个说明性的伪实现。下面的 API 名称具有意向性说明,不应被视为供应商文档。在生产环境中,建议优先使用 SDK 记录的应用级初始化和安装上下文生命周期,而不是将归因检索直接耦合到单个 Activity 生命周期。在投入生产使用前,请针对供应商的当前文档验证所有类、方法名称、回调类型和配置键。
// Android Implementation: ID-Free Parameter Extraction (Architecture Pattern)
// Location in Part A: [CODE_BLOCK_01]
// Note: Illustrative pseudo implementation based on OpoInstall SDK contracts.
// ----------------------------------------------------------------------------
// 1. AndroidManifest.xml (Sample excerpt)
// ----------------------------------------------------------------------------
/*
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application android:name=".CustomApplication" android:label="@string/app_name">
<!-- Configure the application key using the method specified in vendor documentation -->
<meta-data android:name="com.opoinstall.APP_KEY" android:value="YOUR_APPKEY"/>
</application>
</manifest>
*/
// ----------------------------------------------------------------------------
// 2. CustomApplication.kt: Application-Level State-Machine Lifecycle
// ----------------------------------------------------------------------------
package com.example.myapp
import android.app.Application
import android.util.Log
import com.opoinstall.api.OpoData
import com.opoinstall.api.OpoError
import com.opoinstall.api.OpoInstall
import com.opoinstall.api.ResultCallBack
class CustomApplication : Application() {
enum class AttributionState {
NOT_STARTED,
FETCHING,
PROCESSED
}
override fun onCreate() {
super.onCreate()
// Initialize the first-party routing SDK in the main process
OpoInstall.initialize(this)
// Retrieve install context once at the application layer
if (getAttributionState() == AttributionState.NOT_STARTED) {
fetchInstallContext()
}
}
private fun fetchInstallContext() {
setAttributionState(AttributionState.FETCHING)
OpoInstall.getInstance().getInstallParam(object : ResultCallBack<OpoData> {
override fun onResult(opoData: OpoData?) {
setAttributionState(AttributionState.PROCESSED)
if (opoData != null) {
val channelCode = opoData.channelCode
val customData = opoData.data
Log.d("InstallContext", "Restored context: Channel=$channelCode, Data=$customData")
handleInstallContext(channelCode, customData)
}
}
override fun onError(opoError: OpoError?) {
// If a temporary network failure occurs, state can remain retryable or fallback cleanly
Log.w("InstallContext", "Attribution query completed with status: ${opoError?.errorMsg}")
setAttributionState(AttributionState.PROCESSED)
}
})
}
private fun getAttributionState(): AttributionState {
val raw = getSharedPreferences("attribution_prefs", MODE_PRIVATE)
.getString("state", AttributionState.NOT_STARTED.name)
return AttributionState.valueOf(raw ?: AttributionState.NOT_STARTED.name)
}
private fun setAttributionState(state: AttributionState) {
getSharedPreferences("attribution_prefs", MODE_PRIVATE)
.edit()
.putString("state", state.name)
.apply()
}
private fun handleInstallContext(channelCode: String?, customData: String?) {
// Dispatch restored context to internal account/routing services
}
}
iOS 实现:Swift 生命周期集成
在 iOS 上,应用将 SDK 集成在应用生命周期委托中。SDK 在主执行线程上异步检索安装参数,在不执行跨应用跟踪时无需调用 AppTrackingTransparency 授权请求。
下面的 Swift 实现演示了说明性的初始化和参数提取工作流:
// iOS Integration Pattern: Application-Level Install Context Retrieval
// Location in Part A: [CODE_BLOCK_02]
// Note: PSEUDOCODE ONLY. Type and method names are illustrative placeholders.
// ----------------------------------------------------------------------------
// 1. Info.plist (Sample excerpt)
// ----------------------------------------------------------------------------
/*
<!-- Configure the application key using the method specified in vendor documentation -->
<key>com.opoinstall.APP_KEY</key>
<string>YOUR_APPKEY</string>
*/
// ----------------------------------------------------------------------------
// 2. AppDelegate.swift: Lifecycle Initialization and Context Retrieval
// ----------------------------------------------------------------------------
import UIKit
// Note: SDK module import omitted intentionally; use the module name supplied by your package manager.
enum InstallContextState: String {
case notStarted = "NOT_STARTED"
case fetching = "FETCHING"
case processed = "PROCESSED"
}
@main
class AppDelegate: UIResponder, UIApplicationDelegate, OpoInstallDelegate {
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Initialize the first-party routing SDK without invoking ATT authorization
OpoInstallSDK.initWith(self)
// Guard retrieval with state-machine check at the application entry point
if getInstallContextState() == .notStarted {
fetchInstallContext()
}
return true
}
private func fetchInstallContext() {
setInstallContextState(.fetching)
// Retrieve deferred install parameters asynchronously
OpoInstallSDK.defaultManager()?.getInstallParmsCompleted({ [weak self] (appData: OpoinstallData?) in
DispatchQueue.main.async {
self?.setInstallContextState(.processed)
if let data = appData?.data {
let channel = appData?.channelCode
self?.handleInstallContext(channelCode: channel, customData: data)
}
}
})
}
private func getInstallContextState() -> InstallContextState {
let raw = UserDefaults.standard.string(forKey: "install_context_state") ?? InstallContextState.notStarted.rawValue
return InstallContextState(rawValue: raw) ?? .notStarted
}
private func setInstallContextState(_ state: InstallContextState) {
UserDefaults.standard.set(state.rawValue, forKey: "install_context_state")
}
private func handleInstallContext(channelCode: String?, customData: String) {
// Dispatch restored context to internal account/routing services
}
// Universal Link delegate callback for deep linking
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
OpoInstallSDK.continue(userActivity)
return true
}
}
客户端实现的工程考量
-
非阻塞 UI 生命周期:始终异步初始化归因 SDK,并在应用启动期间查询参数而不阻塞主 UI 线程。
-
本地幂等性处理:维护状态机或持久化标志(例如
NOT_STARTED、FETCHING、PROCESSED)以干净地管理参数提取并防止冗余的 API 查询。 -
服务端重放防御:根据后端交易日志验证动态参数负载,以确保引荐代码或促销令牌无法被恶意重放。
平台归因 API 与隐私沙盒过渡
Android 平台归因与隐私沙盒过渡
Android 的归因报告 API 旨在支持跨应用和网页的隐私保护衡量,而不依赖跨方标识符。
Android 的归因报告 API 可用于受支持的隐私沙盒集成,但它们并非 Install Referrer 或 MMP 集成的通用替代品。生产环境的适用性取决于特定的 Android 版本、广告技术集成、注册要求和生态系统支持。在将归因报告作为生产依赖项之前,团队应验证当前的 Android 隐私沙盒文档。
对于通过 Play 分发的 Android 应用,Google Play Install Referrer 仍然是检索与 Play 商店安装相关的营销活动参数的实用第一方机制。广告网络和归因提供商也可能提供平台支持的衡量集成。
Apple 平台归因:AdAttributionKit 与 SKAdNetwork
在 iOS 上,Apple 提供了以 AdAttributionKit 为中心的隐私保护归因机制,它支持整个 App Store 和替代应用市场的应用广告活动,同时与 SKAdNetwork 互操作。这些框架提供平台中介归因信号,而不会暴露持久的设备广告标识符。报告粒度和时效仍受 Apple 隐私阈值和归因窗口管控。
第一方路由与平台 API 的共存
平台隐私 API 和第一方上下文路由解决不同的工程需求:
-
平台隐私 API:专为宏观广告衡量、广告网络 ROI 计算和程序化营销活动优化而设计,无持久标识符。
-
第一方参数路由:专为微观应用引导、即时用户间引荐奖励绑定、深度链接路由和直接 web-to-app 转化旅程而设计。
如何在沙盒环境中验证归因准确性
在无法访问广告 ID 时测试安装归因
为了验证应用在各种设备和权限状态下是否正确处理安装归因:
-
缺少 AD_ID 状态:部署一个从
AndroidManifest.xml中排除com.google.android.gms.permission.AD_ID权限的 Android 测试构建,并验证应用是否干净地初始化。 -
用户标识符限制:在带有 Google Play 服务的 Android 测试设备上,启用广告限制或在系统设置中删除广告 ID,以确保参数提取不会崩溃或挂起。
-
Play 商店营销活动模拟:使用显式通过 Google Play Install Referrer 机制传递预期值的测试营销活动 URL 触发安装旅程。不要假设任意落地页查询参数会自动成为 Install Referrer 值。
-
重新安装验证:在先前已归因的安装后重新安装应用,并验证归因流是否没有错误地复用陈旧的首次安装状态。
-
自然回退验证:启动未链接的构建,以确认
getInstallParam干净地解析为 null 或自然回退,而不会挂起。
在物理 iOS 设备上模拟 ATT 拒绝状态
若要在跟踪被拒绝时测试 iOS 参数检索:
-
通过 Xcode 在物理 iOS 设备上安装测试构建。
-
验证 SDK 参数检索方法是否异步执行并成功解析参数,而无需提示 ATT 或查询 IDFA API。
-
测试冷启动和后台唤醒生命周期的应用启动行为。
审查网络负载的数据最小化
安全和合规团队应使用 HTTP 代理检查客户端网络流量:
-
确认 ID 排除:验证传出的归因请求不包括持久标识符,如 IMEI、MAC 地址、Android ID (
SSAID) 或未授权的 IDFA 字符串。 -
传输安全:确保归因 API 通信使用带有当前 TLS 配置和标准证书验证的 HTTPS。
-
负载保护:确认传输中或临时缓冲区中存储的动态令牌利用适当的保护标准。

常见问题 (FAQ)
没有 GAID 可以进行安装归因吗?
移动测量平台可以在没有 GAID 或 IDFA 的情况下工作吗?
Install Referrer 可以替代 GAID 吗?
当 Android 应用在没有 AD_ID 权限的情况下请求 GAID 时会发生什么?
移除 IDFA 可以免除 Apple ATT 要求吗?
上下文匹配与设备指纹识别是一回事吗?
当无法恢复任何安装参数时会发生什么?
使用 OpoInstall 构建无 ID 归因基础设施
评估独立于广告 ID 的增长技术栈的工程团队需要三项核心技术能力:
-
顺畅的上下文恢复:将自定义元数据从网页落地页传递到原生应用,而无需手动引荐代码或硬件 ID 采集。
-
跨平台营销活动上下文管理:跨平台管理 web-to-app 和移动端营销活动,而无需多个应用构建版本。
-
严格的平台合规:完全在第一方应用沙盒内运行并尊重操作系统隐私限制。
要探索移动测量和路由的实现模式,请查阅 OpoInstall 文档或访问 OpoInstall 开发者控制台。
总结与决策框架
为了在广告标识符限制不断增加的情况下构建可持续的移动增长架构,工程团队必须摆脱对传统 GAID 和 IDFA 的依赖。随着操作系统和监管政策继续限制跨应用跟踪,依赖持久设备标识符会引入结构性脆弱性。
现代归因框架将第一方参数传输、平台中介衡量 API 和具韧性的客户端 SDK 提取相结合。通过部署上下文路由架构,移动团队能够保持可靠的 web-to-app 转化旅程,同时与平台隐私要求保持一致。
相关材料
-
概念:广告 ID 限制、上下文参数路由、Install Referrer、AdAttributionKit、应用跟踪透明度
-
技术:Google Play Install Referrer API、Google Play 服务广告 API、Apple ATT 框架、Apple AdAttributionKit、OpoInstall 移动 SDK
-
安全主题:移动数据最小化、重放保护、传输安全
-
API:Google Play Install Referrer API、谷歌广告 ID API、Apple 应用跟踪透明度 API、OpoInstall 安装参数 API
官方文档
Android
Apple
隐私保护归因
Share this article



