WWDC Quick Look 💓 By SwiftGGTeam
What’s new in AdAttributionKit

What’s new in AdAttributionKit

观看原视频

Highlight

iOS 18.4 起,同一个 App 可以同时持有多个有效的 re-engagement 转化窗口,通过 conversion tag 精确标记每一次广告召回。


核心内容

广告归因里有一个长期被回避的问题:同一时刻只能有一个 re-engagement 转化在跑。假设你同时在投两个促销广告,用户先点了 Discount 1 进入 App 没下单,几小时后又点了 Discount 2,最终回头买了 Discount 1 的商品。在 iOS 18.3 之前,前一个转化早就被锁住,购买数据只能挂到 Discount 2 头上,第一个广告的真实价值被埋没。运营会发现 ROI 数据和直觉对不上,但又找不到归因可以校正的地方。

iOS 18.4 把这个限制拆掉了。多个 re-engagement 转化窗口可以同时存在,每个窗口附带一个 conversion tag,类似一份转化书签。App 在 Info.plist 里把 EligibleForAdAttributionKitOverlappingConversions 设为 YES,AdAttributionKit 就会在 re-engagement URL 上追加一个查询参数;App 取出 tag、本地或服务器持久化,等用户真的下单时拿这个 tag 去更新对应那次转化的 postback。归因从”谁离购买最近”变成”用户究竟是被哪个广告召回的”。


详细内容

整套机制围绕 Postback.reengagementOpenURLParameter 这一个 query item 展开。App 接到 Universal Link 后,从 URL 中抽出 tag 值(05:42):

func retrieveConversionTag(fromURL url: URL) -> String? {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        print("Could not get components for URL.")
        return nil
    }

    guard let queryItems = components.queryItems else {
        print("URL does not contain query items.")
        return nil
    }

    for item in queryItems {
        guard item.name == Postback.reengagementOpenURLParameter else {
            continue
        }
        return item.value
    }
    return nil
}

关键点:

  • URLComponents(url:resolvingAgainstBaseURL:) 解析 deep link,失败直接返回 nil。
  • queryItems 拿到 URL 上所有的查询参数,没有就视为非召回链接。
  • 比对 Postback.reengagementOpenURLParameter,AdAttributionKit 在 re-engagement 打开时一定会附上这个参数。
  • 找到即刻返回 value,这就是后续用于更新的 conversion tag。

拿到 tag 之后,业务侧在用户产生有效行为时调用更新 API(06:55):

func updateConversionValue(_ conversionValue: Int, conversionTag: String) async {
    do {
        let update = PostbackUpdate(fineConversionValue: conversionValue,
                                    lockPostback: false,
                                    conversionTag: conversionTag)
        try await Postback.updateConversionValue(update)
    }
    catch {
        print("An error occurred while updating the conversion value: \(error)")
    }
}

关键点:

  • PostbackUpdate 同时接收 fineConversionValuelockPostbackconversionTag 三个字段。
  • lockPostback: false 表示后续仍允许进一步更新,适合多步漏斗的场景。
  • conversionTag 是定向更新的关键,缺省时系统只会更新最近一次转化。
  • Postback.updateConversionValue 是 async throws,调用方需要在并发上下文里处理错误。

第二条主线是 attribution window 与 cooldown 的可配置化。Info.plist 里新增 AdAttributionKitConfigurations 字段,按 ad network 维度声明窗口长度(10:14):

{
  "AdAttributionKitConfigurations": {
    "AttributionWindows": {
      "com.example.adNetwork": {
        "install": {
          "click": 2,
          "ignoreInteractionType": "view"                     
        }
      }
    }
 }

关键点:

  • AttributionWindows 下用 ad network identifier 作 key,可对每家网络单独配置。
  • install 子节点描述 install 类型的归因;re-engagement 不存在窗口配置,因为转化紧贴交互发生。
  • click 指定点击型广告的归因窗口天数;默认 30 天,可缩短也可延长。
  • ignoreInteractionType 设为 "view""click" 之一,让某一类交互完全不参与该网络的归因。
  • 若需要批量配置,可以再加一个 global key 作为兜底,特定 ad network 的配置覆盖全局值(10:46)。

cooldown 用同一套配置入口表达”转化后封锁期”(13:52)。把 install-cooldown-hours 设为 6、reengagement-cooldown-hours 设为 1,就能避免 install 转化刚发生几分钟后就被一次 re-engagement 抢走归因。

postback 这次还多了一项 country-code17:05),值是符合 ISO 3166 的两位国家码,比如 "MT"。Marketplace 场景下,install verification token payload 中也对应多了 ccode 字段(16:26),让广告网络可以按地区拆分预算效果。


核心启发

  • 打开 overlapping conversions 并接入 conversion tag:为什么值得做:多个 re-engagement 同时跑是促销季常态,旧规则会让早期广告的真实价值被系统性低估。怎么开始:在 Info.plistEligibleForAdAttributionKitOverlappingConversions=YES,在 Universal Link 处理函数里读取 Postback.reengagementOpenURLParameter 并把 tag 与本地订单上下文绑定。

  • 按 ad network 单独裁剪归因窗口:为什么值得做:默认 30 天的 click 窗口对短促销根本不合理,会把无关流量计入归因;缩短窗口能让数据反映真实购买动机。怎么开始:先用 App Analytics 数据看出每家网络的实际转化时间分布,再为典型转化时间偏短的网络在 AttributionWindows 里设定 2–7 天的 click 窗口,对纯展示型网络用 ignoreInteractionType: "view" 直接剔除。

  • 为关键转化路径设置 cooldown:为什么值得做:install 完成几分钟内被 re-engagement 截胡是真实存在的误归因,会让买量团队和召回团队的数据互相打架。怎么开始:先观察 IAP 与 install 的时间间隔分布,设 install-cooldown-hours 为大多数首购完成的时长(例如 6 小时),reengagement-cooldown-hours 设为 1 小时,再用 iOS Settings 里的 AdAttributionKit 测试入口走通端到端。

  • 消费 postback 时纳入 country-code 维度:为什么值得做:同一个 ROAS 数字在不同国家的含义差异很大,把地区拆开后才能定位真正赚钱的市场。怎么开始:在 postback 入库脚本里新增 country-code 字段;Marketplace 流程额外解析 token payload 中的 ccode,作为合规与对账的双重凭据。


关联 Session

评论

GitHub Issues · utterances