更新记录

1.0.0(2026-09-22)

支持 AppsFlyer广告归因


平台兼容性

uni-app(5.26)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Safari app-vue app-vue插件版本 app-nvue app-nvue插件版本 Android Android插件版本 iOS iOS插件版本 鸿蒙
1.0.0 1.0.0 × × 1.0.0 1.0.0 5.0 1.0.0 12 1.0.0 ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

uni-app x(5.26)

Chrome Safari Android Android插件版本 iOS iOS插件版本 鸿蒙 微信小程序
× × 5.0 1.0.0 12 1.0.0 × ×

tt-appsflyer-sdk

面向 uni-appuni-app x 的 AppsFlyer UTS 插件,支持 Android/iOS 安装归因、事件上报、Customer User ID 和 Unified Deep Linking(UDL)。

目录

SDK 版本

平台 AppsFlyer SDK
Android 7.0.1
iOS 7.0.1

重要提示

  1. Android/iOS 必须使用自定义基座或正式原生构建。
  2. 归因和深链功能必须使用真实设备验证。
  3. 完成隐私同意流程后,再调用 start
  4. Dev Key、package name、Bundle ID、签名证书和 Apple App ID 必须与 AppsFlyer 控制台配置一致。
  5. 不要将真实 Dev Key 写入公共仓库。
  6. 当前原生功能支持 Android 和 iOS。

环境配置

AppsFlyer 控制台

使用前请在 AppsFlyer 控制台准备:

  1. Android 或 iOS 应用。
  2. AppsFlyer Dev Key。
  3. Android package name 或 iOS Bundle ID。
  4. iOS Apple App ID。
  5. OneLink 模板或 OneLink 自定义域名。
  6. 测试设备和测试链接。

Android

在 AppsFlyer 控制台配置 Android 应用的 package name 和签名证书。

Android App Links

如果使用 HTTPS App Links,需要在宿主原生工程中配置 intent-filter,并在域名侧部署 assetlinks.json。下面的 Activity 名称仅为示例,实际名称以 HBuilderX 导出的宿主工程为准:

<activity
    android:name="io.dcloud.PandoraEntry"
    android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="https"
            android:host="yourbrand.onelink.me" />
    </intent-filter>
</activity>

assetlinks.json 至少需要与正式构建的 package name 和 SHA-256 签名指纹匹配。调试签名和正式签名通常需要分别配置。

iOS

宿主应用需要配置:

  • Apple App ID;
  • Bundle ID;
  • NSUserTrackingUsageDescription
  • ATT 授权流程;
  • Associated Domains;
  • OneLink Universal Link;
  • 域名侧 apple-app-site-association

ATT 隐私描述

NSUserTrackingUsageDescription 必须合并到宿主应用的 Info.plist,文案应符合真实用途和隐私政策:

<key>NSUserTrackingUsageDescription</key>
<string>我们会使用设备信息改善广告投放效果并衡量推广转化。</string>

以上配置需要在宿主应用中完成。

iOS Universal Links

宿主应用需要启用 Associated Domains,例如:

applinks:yourbrand.onelink.me

同时确认以下配置全部完成:

  1. Apple Developer 中已启用 Associated Domains 能力。
  2. Xcode/云打包配置中包含正确的 entitlements。
  3. OneLink 已关联当前 Bundle ID。
  4. 域名侧已部署正确的 apple-app-site-association
  5. 测试设备安装的是包含 Associated Domains 能力的正式签名包或自定义基座。

完成配置后,插件会接收 URL Scheme 和 Universal Link 回调。

快速开始

导入插件

uni-app x

import * as appsflyer from '@/uni_modules/tt-appsflyer-sdk'

const sdk = appsflyer.getTTAppsFlyerSDK()

uni-app

import * as appsflyer from '@/uni_modules/tt-appsflyer-sdk'

const sdk = appsflyer.getTTAppsFlyerSDK()

初始化 SDK

initialize 只配置原生 SDK 和回调监听,不发送首个 session。建议在隐私同意状态确定后调用 start

const sdk = appsflyer.getTTAppsFlyerSDK()

sdk.initialize({
  devKey: 'your-dev-key',
  // Android 可省略;iOS 填写 Apple App ID 数字部分
  appId: '1234567890',
  isDebug: true,
  success: () => {
    console.log('AppsFlyer 初始化成功')
  },
  fail: (error) => {
    console.error('AppsFlyer 初始化失败', error)
  },
  onConversionDataSuccess: (result) => {
    console.log('安装归因', result.data)
  },
  onConversionDataFail: (error) => {
    console.error('安装归因失败', error)
  },
  onDeepLink: (result) => {
    console.log('Unified Deep Link', result)
  }
})

appId 在 Android 上会被忽略,在 iOS 上必填。iOS App ID 只填写数字部分,不要填写 id 前缀。

启动首个 session

// 仅 iOS 有效;必须在 start 前调用
sdk.waitForATTUserAuthorization(60)

sdk.start({
  success: () => {
    console.log('AppsFlyer session 已启动')
  },
  fail: (error) => {
    console.error('AppsFlyer session 启动失败', error)
  },
  complete: () => {
    console.log('start 完成')
  }
})

uni-app x 类型提示

如果在 uni-app x 中需要显式标注参数类型,可以从插件导入类型:

import * as appsflyer from '@/uni_modules/tt-appsflyer-sdk'

const sdk = appsflyer.getTTAppsFlyerSDK()

sdk.logEvent({
  eventName: 'demo_button_click',
  eventValues: {
    source: 'home'
  } as UTSJSONObject
} as appsflyer.TTAppsFlyerEventOptions)

API 参考

getTTAppsFlyerSDK

getTTAppsFlyerSDK(): TTAppsFlyerSDK

返回 AppsFlyer SDK 单例。

initialize

initialize(options: TTAppsFlyerInitializeOptions): void
参数 类型 必填 说明
devKey string AppsFlyer Dev Key。为空返回 1001
appId string \| null iOS 是 Apple App ID 数字部分,Android 忽略。
isDebug boolean 原生 debug 日志,生产环境建议关闭。
success callback 本地 SDK 配置完成。
fail callback 参数错误或原生异常。
complete callback 成功或失败后执行。
onConversionDataSuccess callback 安装归因数据回调。
onConversionDataFail callback 安装归因失败回调。
onDeepLink callback UDL 结果回调。

success 不代表 AppsFlyer 后台归因成功。归因结果通过 onConversionDataSuccess 异步返回。

start

start(options: TTAppsFlyerStartOptions | null): void
参数 类型 说明
success callback Android 表示 AppsFlyer 请求成功;iOS 表示启动回调未返回错误。
fail callback SDK 未初始化、原生上下文不可用或请求失败。
complete callback 成功或失败后执行。

logEvent

logEvent(options: TTAppsFlyerEventOptions): void
参数 类型 必填 说明
eventName string AppsFlyer 预定义或自定义事件名。
eventValues UTSJSONObject JSON 兼容的事件参数。
success callback 原生 SDK 接受或发送请求。
fail callback 参数错误或请求失败。
complete callback 成功或失败后执行。
sdk.logEvent({
  eventName: 'af_purchase',
  eventValues: {
    af_revenue: 19.9,
    af_currency: 'CNY',
    af_order_id: 'order_10001'
  } as UTSJSONObject,
  success: () => {
    console.log('事件已发送')
  },
  fail: (error) => {
    console.error('事件发送失败', error)
  }
})

事件成功回调只表示 SDK 接受或发送请求,不代表 AppsFlyer 后台已经完成归档。支付、订单等关键业务仍应以服务端状态为准。

setCustomerUserId

setCustomerUserId(customerUserId: string): void

建议在用户登录成功后调用:

sdk.setCustomerUserId('user_10001')

不要未经隐私合规评估直接使用身份证号、手机号等敏感信息。

getAppsFlyerUID

getAppsFlyerUID(): string | null

同步返回 AppsFlyer UID。SDK 尚未生成 UID 时返回 null,不能把 null 当作归因失败。

setDebugLog

setDebugLog(enabled: boolean): void

开启或关闭原生 AppsFlyer debug 日志。生产环境建议关闭。

waitForATTUserAuthorization

waitForATTUserAuthorization(timeoutSeconds: number): void

仅 iOS 有效,必须在 start 前调用。是否请求 ATT 取决于宿主应用的隐私策略。

stop

stop(isStopped: boolean): void
sdk.stop(true)  // 停止采集
sdk.stop(false) // 恢复采集

安装归因

Conversion Data

安装归因通过 onConversionDataSuccess 异步返回:

onConversionDataSuccess: (result) => {
  const data = result.data
  console.log('af_status', data['af_status'])
  console.log('media_source', data['media_source'])
  console.log('campaign', data['campaign'])
}

常见字段:

字段 说明
af_status 通常为 OrganicNon-organic
media_source 媒体来源
campaign Campaign 名称
af_channel 渠道名称,是否存在取决于链接和配置
is_first_launch 是否首次启动
is_deferred 是否与延迟深链相关

字段可能缺失、为空或因 AppsFlyer 隐私策略受到限制。安装归因和 UDL 是两条独立回调链,业务页面路由应优先使用 onDeepLink

归因失败

onConversionDataFail: (error) => {
  console.error(error.errCode, error.errMsg)
}

安装归因回调通常只在首次安装或满足 AppsFlyer 归因条件时出现。测试时应卸载旧应用并使用测试链接重新安装。

Unified Deep Linking

回调结果

onDeepLink: (result) => {
  console.log(result.status)
  console.log(result.deepLinkValue)
  console.log(result.isDeferred)
  console.log(result.data)
}
status 含义 建议处理
FOUND 找到可解析的深链 根据 deepLinkValue 路由
NOT_FOUND 没有匹配到深链 进入默认页面
ERROR 深链解析失败 记录错误,不阻塞应用启动

插件会统一转换以下标准字段:

  • deep_link_value
  • is_deferred
  • media_source
  • campaign

Android/iOS 原生回调中额外 OneLink 参数的透传能力可能不同,当前版本不承诺所有自定义参数都能完整出现在 data 中。业务路由建议始终使用 deep_link_value

OneLink 参数示例

{
  "deep_link_value": "product",
  "deep_link_sub1": "sku_10001"
}

业务路由示例

onDeepLink: (result) => {
  if (result.status != 'FOUND') return

  if (result.deepLinkValue == 'product') {
    const sku = result.data['deep_link_sub1']
    console.log('打开商品', sku)
  }
}

isDeferred == true 表示用户先点击链接、后安装应用,并在首次启动时收到延迟深链结果。

错误处理

失败回调返回 IUniError,错误主体固定为 TTAppsFlyerSDK

{
  errSubject: 'TTAppsFlyerSDK',
  errCode: 1003,
  errMsg: 'SDK尚未初始化'
}

错误码

错误码 含义
1001 Dev Key 为空
1002 iOS App ID 为空
1003 SDK 尚未初始化
1004 SDK 已经初始化,当前版本预留
1005 eventName 为空
1006 customerUserId 为空,当前版本预留
1007 timeoutSeconds 小于 0,当前版本预留
1008 AppsFlyer SDK 请求失败
1009 AppsFlyer 原生回调数据异常
1010 当前平台不支持,当前版本预留
1011 AppsFlyer 原生 SDK 异常
9999 其他错误

常见问题

为什么普通运行基座找不到插件?

Android/iOS 依赖原生 AppsFlyer SDK,标准基座不包含这些依赖。请制作自定义基座或进行正式原生构建。

initialize 成功但没有归因回调?

initialize.success 只表示本地配置成功。请确认:

确认已调用 start,设备处于首次安装状态,应用标识和 Dev Key 配置正确,并等待异步回调。

事件发送成功但后台没有数据?

事件成功回调只表示原生 SDK 接受或发送请求。AppsFlyer 后台存在处理延迟,请先检查设备 debug 日志、事件名、Dev Key 和应用标识。

iOS 没有深链回调?

检查 Associated Domains、applinks: 域名、Apple Developer 能力、entitlements、apple-app-site-association、OneLink 关联和正式签名包。

Android 深链打开浏览器或应用商店?

检查 package name、签名证书、assetlinks.json、Manifest intent-filter、OneLink 路由和 android:autoVerify 配置。调试签名和正式签名不能混用。

deferred deep link 和 Conversion Data 有什么区别?

Conversion Data 用于安装归因,UDL 用于业务深链路由。页面跳转应以 onDeepLink 为准,不能用 Conversion Data 替代 UDL。

ATT 是否一定要调用?

是否请求 ATT 取决于宿主应用的隐私策略。如果需要等待授权,必须在 start 前调用 waitForATTUserAuthorization。ATT 不等于 SDK 初始化成功,也不保证一定得到归因。

官方文档

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: