更新记录
1.2.0(2026-09-10) 下载此版本
新增 $Exception 采集
Changelog
Sensors Wave UniApp X 数据采集 SDK 的所有显著变更均记录于此文件。 格式参考 Keep a Changelog, 版本号遵循 Semantic Versioning。
[1.2.0] - 2026-09-10
新增
- 新增 $Exception 采集
[1.1.0] - 2026-08-14
新增
- 新增安全合规,支持禁用数据采集,用户允许之后才采集。
- $AppInstall 新增 $install_time,记录 App 安装时间。
[1.0.0] - 2026-07-27
新增
- Sensors Wave 数据采集 SDK 正式发布
1.1.0(2026-08-14) 下载此版本
- 新增安全合规,支持禁用数据采集,用户允许之后才采集。
- $AppInstall 新增 $install_time,记录 App 安装时间。
1.0.0(2026-07-27) 下载此版本
Sensors Wave 数据采集 SDK 正式发布
Changelog
Sensors Wave UniApp X 数据采集 SDK 的所有显著变更均记录于此文件。 格式参考 Keep a Changelog, 版本号遵循 Semantic Versioning。
[1.0.0] - 2026-07-27
新增
- Sensors Wave 数据采集 SDK 正式发布
平台兼容性
uni-app x(4.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| √ | √ | √ |
Sensorswave UniApp X 数据采集 SDK
Sensors Wave UniApp X 数据采集 SDK 是一个跨平台的数据埋点采集库,一套代码即可在多个平台自动采集用户行为数据。
以 uni-app-x 的 uni_modules 插件形态发布,业务工程通过 app.use(Sensorswave.plugin, config) 一行接入,应用级预置事件自动采集。
如果你是第一次接触 Sensors Wave,欢迎访问 sensorswave.com 了解产品并创建账号。
源码位于 uni_modules/sensorswave-uniappx/。
特性
- 🌐 跨平台支持:微信 / 支付宝 / 抖音 / 百度小程序、App(iOS / Android / 鸿蒙)、H5
- 🔎 平台运行时探测:通过
uni.getSystemInfoSync()自动识别宿主平台,无需手填platformType/platformName - 🚀 应用级预置事件自动采集:
app.use()后无需在App.uvue手动调用应用级生命周期方法 - 📄 页面级预置事件:由
install()注入的全局 mixin 统一驱动(H5 配合vue-router.afterEach),业务页面零侵入 - 👤 用户体系:匿名 / 登录用户标识、用户属性(profile)增删改、公共属性注册
- 🧪 A/B 测试:功能开关(Feature Gate)、远程配置(Feature Config)、实验分组(Experiment)
- 📡 UTM 追踪:自动解析启动参数中的 UTM 渠道参数并写入首值归因
- 🔒 敏感字段脱敏:自定义事件属性中的敏感信息(token / password / cookie …)自动掩码
- 💾 离线持久化:事件队列持久化存储、批量上报、失败重试,保障数据不丢
- ♻️ 挂起离开恢复:进程被杀后下次启动自动补发未结束会话的离开事件
- 💥 异常采集($Exception):error 级自动捕获(小程序 / H5 / 鸿蒙)+ fatal 级崩溃采集(App 端原生钩子,崩溃前落盘、下次启动补发),支持
trackException手动上报
平台支持
| 平台 | 自动采集事件 |
|---|---|
| 微信小程序 | $MPLaunch $MPShow $MPHide $MPPageView $MPPageLeave $MPShare |
| 支付宝小程序 | 同微信小程序 |
| 抖音小程序 | 同微信小程序 |
| 百度小程序 | 同微信小程序 |
| App iOS / Android / 鸿蒙 | $AppStart $AppEnd $AppPageView $AppPageLeave $AppInstall |
| H5 | $PageView $PageLeave $PageLoad $WebClick |
- 平台在运行时通过
uni.getSystemInfoSync()自动识别,无需手动指定。 - 所有平台上报事件的
$lib预置属性统一为uniappx,用于在数据端标识本采集 SDK。 $WebClick需开启enableClickTrack: true;$MPShare需开启enableShareTrack(默认开启)。
安装
SDK 已发布到 DCloud 插件市场,推荐通过 HBuilderX 一键导入:
- 打开插件市场页面:Sensors Wave uni-app x 数据采集 SDK
- 点击页面上的 使用 HBuilderX 导入插件 按钮
- 在 HBuilderX 弹窗中选择目标 UniApp X 工程,确认导入
- 等待下载完成,插件会自动安装到工程的
uni_modules/目录下
导入完成后,工程结构如下:
your-app/
└── uni_modules/
├── sensorswave-uniappx/ ← 由插件市场自动导入
│ ├── package.json
│ └── utssdk/
└── sw-ios-crash-trigger ← 依赖插件,自动跟随导入
├── package.json
└── utssdk/app-ios/
第二个插件 sw-ios-crash-trigger 是本 SDK 在 App-iOS 端 fatal 崩溃采集的
原生面(iOS 崩溃捕获必须在原生层进行,而编译器规则决定它只能以独立插件形态进基座),已在本
插件 package.json 的 uni_modules.dependencies 中声明——HBuilderX 导入主插件时会提示
"安装插件三方依赖",确认后自动带入,业务代码无需也无法直接调用它。
私有 zip 分发时请确保两个插件目录同时解压到工程的
uni_modules/下。
无需 npm 安装;uni-app-x 会自动识别 uni_modules 插件。后续插件更新也可在 HBuilderX 中通过插件市场一键升级。
如果你需要本地调试或二次开发,也可以将本仓库的
uni_modules/sensorswave-uniappx/与uni_modules/sw-ios-crash-trigger/两个目录拷贝(或软链)到工程的uni_modules/下,效果一致。
快速开始
推荐通过 Vue 插件 接入,插件会在 app.use() 时自动完成初始化,并注入页面生命周期 mixin,实现无侵入的页面浏览 / 离开采集。
1. 在 main.uts 安装插件
import App from './App.uvue'
import { createSSRApp } from 'vue'
import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index'
export function createApp() {
const app = createSSRApp(App)
app.use(Sensorswave.plugin, {
sourceToken: 'your_source_token', // 必填:数据源 Token
apiHost: 'https://example.com', // 必填:数据上报地址
autoCapture: true, // 自动采集生命周期(默认 true)
enableClickTrack: true, // 自动采集点击(默认 false)
enableAB: true, // 启用 A/B 测试(默认 false)
debug: false, // 调试日志(默认 false)
})
return { app }
}
2. App.uvue 无需手动调用应用级预置事件
应用级事件(启动 / 前后台切换 / 小程序分享)由 SDK 在 install() 内自动监听与触发,
App.uvue 只需放置与业务身份相关的逻辑:
<script setup lang="uts">
import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index'
onLaunch((options : any) => {
// 仅在已登录场景下设置 loginId(可选)
Sensorswave.setLoginId('user_123')
})
</script>
不需要调用
Sensorswave.onAppLaunch / onAppShow / onAppHide / onShare—— 它们会被自动触发。 页面级生命周期方法(onPageShow/onPageHide/onPageUnload)也不再对外暴露。
3. 页面级事件接入
通过 Vue 插件接入(推荐)后,页面级事件($PageView / $*PageLeave / $PageLoad)由 install() 注入的全局 mixin 统一驱动,业务页面零侵入:
- H5:全局 mixin +
vue-router.afterEach共同生效 - 小程序 / App:全局 mixin 合并到 App 根组件、页面及所有自定义组件,SDK 内部通过
$scope.route/$page.route/$options.mpType === 'page'过滤出真正的页面实例,避免 App 根组件 / 子组件的onShow误触发$MPPageView/$AppPageView
备选方案:如果你直接调用
Sensorswave.init(sourceToken, config)(不走app.use()),没有app实例注册全局 mixin,需要在每个页面手动集成:
<script setup>(推荐):<script setup lang="uts"> import { useSensorswavePageLifecycle } from '@/uni_modules/sensorswave-uniappx/utssdk/index' useSensorswavePageLifecycle() </script>Options API:
import { SensorswavePageMixin } from '@/uni_modules/sensorswave-uniappx' export default { mixins: [SensorswavePageMixin], }
4. 在组件中调用
插件安装后,SDK 实例会挂载到 Vue 全局属性 $sensorswave:
- Options API:可通过
this.$sensorswave访问。 <script setup>:没有this,直接import Sensorswave调用单例即可(推荐)。
无论哪种写法,拿到的是同一个 SDK 单例,调用方式完全一致。
import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index'
// 自定义事件(推荐:使用 trackEvent)
Sensorswave.trackEvent('button_click', { button_name: 'submit', amount: 99 })
⚠️ 导入方式约定:统一使用深路径导入
import Sensorswave from '@/uni_modules/sensorswave-uniappx/utssdk/index',且同一应用内所有文件保持一致(混用不同导入路径会产生两份 SDK 单例,事件分裂)。⚠️
sourceToken和apiHost为必填项,缺失会导致数据无法上报(SDK 会在控制台输出告警)。
配置项
| 配置 | 类型 | 默认值 | 说明 |
|---|---|---|---|
sourceToken |
string |
'' |
必填。数据上报凭证,由服务端分配 |
apiHost |
string |
'' |
必填。数据上报 API 地址 |
debug |
boolean |
false |
是否开启调试模式,输出详细日志 |
autoCapture |
boolean |
true |
是否自动采集生命周期事件(启动、前后台、页面浏览等) |
batchSend |
boolean |
false |
是否启用批量发送(关闭则即时发送) |
maxBatchSize |
number |
10 |
批量发送时每批最大事件数 |
flushInterval |
number |
5000 |
批量发送轮询间隔(毫秒) |
enableClickTrack |
boolean |
false |
是否自动采集元素点击($WebClick),仅 H5 支持 |
enableShareTrack |
boolean |
true |
是否自动采集小程序分享(仅 MP) |
enableAB |
boolean |
false |
是否启用 A/B 测试功能 |
enableErrorTrack |
boolean |
false |
是否自动采集 error 级异常($Exception,$exception_level = error)。平台捕获面见异常采集 |
enableCrashTrack |
boolean |
false |
是否采集 fatal 级崩溃($Exception,$exception_level = fatal,仅 App)。iOS 端需自定义基座,见自定义基座与真机调试说明 |
abRefreshInterval |
number |
600000 |
A/B 测试缓存刷新间隔(毫秒,默认 10 分钟,最小 30 秒) |
optOutCapturing |
boolean |
false |
合规:初始化即禁用采集(不发、不读、不写任何埋点数据),满足 GDPR / 隐私法规的「默认不采集」诉求 |
persistOptOut |
boolean |
false |
合规:是否将 opt-out 状态持久化到本地存储,使其跨会话保留(进程重启 / destroy 后重新初始化仍恢复用户的授权决策) |
💡
optOutCapturing/persistOptOut的运行时行为见 合规(禁用采集) 小节。
API 方法
事件追踪
trackEvent(eventName, properties?)
手动上报一个自定义事件。时间戳默认取当前时刻。
eventName(string,必填):事件名称properties(object,可选):事件属性
Sensorswave.trackEvent('OrderSubmit', {
order_id: 'ORDER_001',
amount: 99.9,
currency: 'CNY',
})
track - 高级事件追踪
发送完整的事件对象,支持更精细的控制。此方法允许您手动指定所有事件字段。
参数:
event(必填):完整事件对象,包含以下字段:event(string,必填):事件名称properties(Record<string, any>,可选):事件属性time(number,可选):时间戳(毫秒),缺省时 SDK 取当前时刻anon_id(string,可选):匿名用户 ID,缺省时从 store 读取login_id(string,可选):登录用户 ID。login_id和anon_id至少传一个;都传时优先login_id;都缺省时从 store 兜底trace_id(string,可选):请求追踪 ID,缺省时 SDK 自动生成 UUIDuser_properties(Record<string, any>,可选):用户属性,透传
示例:
Sensorswave.track({
event: 'purchaseCompleted',
properties: {
product_id: '12345',
amount: 99.99,
currency: 'USD'
},
time: Date.now(),
trace_id: 'unique-trace-id-12345',
anon_id: 'anonymous-user-id',
login_id: 'user_12345',
user_properties: {
// $set: 代表插入或者更新一条用户属性信息
$set: {
plan: 'premium',
signup_date: '2024-01-01'
}
}
});
// 也可只传 event 名称,其余字段由 SDK 兜底
Sensorswave.track({ event: 'OrderPaid' });
💡 普通业务事件请优先使用
trackEvent,仅在需要精确控制time/trace_id/user_properties等字段时使用track。
用户标识
identify(loginId)
设置登录 ID,并发送 $Identify 事件,将匿名行为与登录用户关联。
Sensorswave.identify('user_12345')
setLoginId(loginId)
设置登录 ID,不发送 $Identify 事件。仅需要标识用户、不需要追踪关联事件时使用。
Sensorswave.setLoginId('user_12345')
getLoginId()
获取当前登录用户 ID,未登录或未初始化时返回空字符串。返回 string。
const loginId = Sensorswave.getLoginId()
getAnonId()
获取当前匿名用户 ID,该 ID 在设备首次使用时自动生成并持久化。返回 string。
const anonId = Sensorswave.getAnonId()
reset(resetAnonId?)
用户登出时调用,解除登录 ID 与设备的绑定。默认保留匿名 ID,登出后事件改以原匿名 ID 继续标识。 同时会失效 A/B 测试身份缓存,后续实验按新身份重新分组。不发送任何服务端事件。
resetAnonId(boolean,可选):是否同时重置匿名 ID,默认false
// 用户登出时
Sensorswave.reset() // 默认保留匿名 ID
// 如果需要同时重置匿名 ID(如公共设备场景)
Sensorswave.reset(true)
用户属性(Profile)
profileSet(properties)
设置用户属性,已存在的属性会被覆盖。
Sensorswave.profileSet({
name: 'alice',
age: 30,
plan: 'premium',
})
profileSetOnce(properties)
首次设置用户属性,已存在的属性不会被覆盖。常用于记录首次注册时间、首次来源等。
Sensorswave.profileSetOnce({
signup_date: '2026-01-15',
initial_referrer: 'google',
})
profileIncrement(properties)
对数值型用户属性进行递增操作,仅支持数值类型,支持正数和负数。
// 递增单个属性
Sensorswave.profileIncrement({ login_count: 1 })
// 递增多个属性
Sensorswave.profileIncrement({
login_count: 1,
points_earned: 100,
})
profileAppend(properties)
向数组类型的用户属性追加元素,不去重。
Sensorswave.profileAppend({
categories_viewed: ['electronics', 'mobile_phones'],
})
profileUnion(properties)
向数组类型的用户属性追加元素,自动去重。
Sensorswave.profileUnion({
interests: ['technology', 'gaming'],
})
profileUnset(keys)
删除指定的用户属性。
keys(string[],必填):要删除的属性名数组
// 删除单个属性
Sensorswave.profileUnset(['temporary_campaign'])
// 删除多个属性
Sensorswave.profileUnset(['old_plan', 'expired_flag'])
profileDelete()
删除当前用户的全部用户属性数据,操作不可恢复。仅对已登录用户有效。
Sensorswave.profileDelete()
公共属性
公共属性会自动附加到后续上报的所有事件上,适合注入全局上下文(如应用版本、环境等)。
值支持静态值(字符串 / 数值 / 布尔等),也支持动态函数——函数会在每次事件构建时调用取最新值,
例如 now: () => Date.now()、$screen: () => getCurrentPage().route 等场景都能正确取到当前时刻 / 当前页。
registerCommonProperties(properties)
注册公共属性,已存在的同名属性会被覆盖。
// 静态公共属性
Sensorswave.registerCommonProperties({
app_version: '1.0.0',
environment: 'production',
app_channel: 'wechat',
})
// 动态公共属性:每次事件上报时实时求值
Sensorswave.registerCommonProperties({
$current_time: () => Date.now(),
$active_page: () => getCurrentPages().pop()?.route ?? '',
})
clearCommonProperties(keys?)
清除已注册的公共属性。不传 keys 时清除全部。
// 清除指定公共属性
Sensorswave.clearCommonProperties(['app_version', 'app_channel'])
// 清除全部公共属性
Sensorswave.clearCommonProperties()
A/B 测试
需在初始化时设置
enableAB: true,否则以下方法将直接返回默认值。
checkFeatureGate(key)
检查功能开关(Feature Gate)是否对当前用户开启。返回 Promise<boolean>。
const enabled = await Sensorswave.checkFeatureGate('new_checkout_flow')
if (enabled) {
showNewCheckout()
}
getFeatureConfig(key)
获取远程配置(Feature Config)。服务端返回的 JSON 字符串会被自动解析。返回 Promise<Record<string, any>>,未启用 A/B 测试时返回空对象 {}。
const config = await Sensorswave.getFeatureConfig('app_settings')
const { theme, layout } = config
getExperiment(key)
获取实验分组(Experiment)。返回 Promise<Record<string, any>>,未命中实验或未启用 A/B 测试时返回空对象。
const exp = await Sensorswave.getExperiment('homepage_layout')
const { layout_type } = exp
异常采集($Exception)
需在初始化时设置
enableErrorTrack: true(error 级)和 / 或enableCrashTrack: true(fatal 级),两者均默认关闭、互不依赖。
error 级自动捕获(enableErrorTrack)
自动采集未捕获的 JS 异常与 Promise 拒绝,上报为 $Exception($exception_level = error)。各平台捕获面:
| 平台 | 捕获机制 |
|---|---|
| 小程序 | uni.onError + uni.onUnhandledRejection(个别平台缺失时静默降级,如支付宝无 onError) |
| H5 | uni.onError(Vue 捕获面)+ window.error / unhandledrejection(逃逸 Vue 的异步错误) |
| App 鸿蒙 | 应用级 onError 钩子(鸿蒙运行时恒装 Vue errorHandler,组件回调内的同步 throw 进程不崩溃) |
| App Android / iOS | 无 JS 级错误钩子(uni-app x 运行时会 catch 住组件回调里的异常仅打日志)——未捕获异常即进程崩溃,走下方 fatal 通道;已捕获的异常(业务 try-catch 拿到的)用 trackException 手动上报 |
fatal 级崩溃采集(enableCrashTrack,仅 App)
通过各平台原生机制捕获「未捕获异常导致进程终止」级崩溃:崩溃瞬间把最小 payload(类型 / message / 堆栈 / 结构化帧)同步落盘,进程死亡;下次启动 SDK 自动补发为 $Exception($exception_level = fatal,事件时间为崩溃时刻而非补发时刻)。
| 平台 | 崩溃捕获机制 | 覆盖范围 |
|---|---|---|
| Android | Thread.setDefaultUncaughtExceptionHandler |
JVM 任意线程未捕获异常 |
| iOS | NSSetUncaughtExceptionHandler(经配套原生插件,见自定义基座与真机调试说明) |
NSException 级未捕获异常;SIGSEGV 等信号级崩溃不覆盖 |
| 鸿蒙 | 双通道:errorManager(未捕获 JS 异常,进程不退出)+ hiAppEvent watcher(系统 faultlog,下次启动回放 C++ crash / 卡死等真崩溃) |
两通道以 ±5s 崩溃时刻窗口判重,防同一崩溃双计 |
约束:待补发记录上限 10 条(超出淘汰最旧)、有效期 7 天;落盘前检查持久化 opt-out 标志(见合规)。
trackException(throwable, properties?)
手动上报一条 $Exception($exception_level = error),不受任何开关限制。适合业务 try-catch 拿到异常后主动上报——也是 Android / iOS 端 error 级采集的唯一通道。
try {
riskyBusiness()
} catch (e) {
Sensorswave.trackException(e, { source: 'manual_catch', page: 'OrderPage' })
}
$Exception 事件属性
| 属性 | 说明 |
|---|---|
$exception_level |
error(自动捕获 / 手动上报)或 fatal(崩溃补发) |
$exception_type |
异常类型名(如 TypeError / NSInvalidArgumentException / JVM 全类名) |
$exception_message |
异常 message |
$exception_frames |
结构化堆栈帧(平台家族路由符号化;仅解析出帧时上报,无空数组占位) |
💡 iOS 崩溃的结构化帧在崩溃时刻预解析落盘(
image_addr依赖崩溃现场 ASLR 布局,不可事后重算),补发时直通使用。
合规(禁用采集)
为满足 GDPR 等隐私法规要求,SDK 提供 opt-out(禁用采集)能力。禁用期间,SDK 不发、不读、不写 任何埋点数据——所有事件上报、用户标识读写、公共属性写入、A/B 查询等对外 API 均为 no-op 且不抛错;唯一例外是 UTM 启动参数仍会静默捕获到内存,以便用户重新授权后补发首触归因。
以下三个方法均可在 init() / app.use() 之前调用(init 时会按优先级合并):
optOutCapturing()
立即禁用所有采集与上报:置内存标记并暂停发送器;若开启 persistOptOut: true,状态会同步写入本地存储(跨会话保留)。可在 init 前调用。
// 例:用户在隐私弹窗中拒绝授权
Sensorswave.optOutCapturing()
optInCapturing()
解除禁用状态,恢复正常的采集与上报流程。若禁用期间首触归因事件($UserSet)从未发送过,则使用禁用期间静默捕获的 UTM 的原始时间补发一次;禁用期间发生的其他事件一律不补发。可在 init 前调用。
// 例:用户在隐私弹窗中同意授权
Sensorswave.optInCapturing()
hasOptedOutCapturing()
查询当前是否处于禁用采集状态。返回 boolean(true = 已禁用,不发不读不写)。
if (Sensorswave.hasOptedOutCapturing()) {
// 当前已禁用采集
}
初始化时的状态合并优先级
init() 阶段会按以下优先级确定最终的 opt-out 状态(高优先级覆盖低优先级):
- init 前 API 已 opt-out(调用过
optOutCapturing())→ 保留禁用状态 - config 显式
optOutCapturing: true→ 强制禁用 persistOptOut: true且本地有持久化值(如destroy后重新初始化)→ 从本地存储恢复用户的授权决策
// 典型用法:默认禁用采集,由用户授权后再开启,且授权决策跨会话保留
app.use(Sensorswave.plugin, {
sourceToken: 'your_source_token',
apiHost: 'https://example.com',
optOutCapturing: true, // 默认禁用,等用户授权
persistOptOut: true, // 授权决策持久化,重启后仍生效
})
// 用户同意授权后开启
Sensorswave.optInCapturing()
⚠️ 授权决策属于合规语义,
destroy()不会 清除本地持久化的 opt-out 状态;重新初始化时若persistOptOut: true,仍会恢复用户上一次的授权选择。
其他
isInitialized()
查询 SDK 是否已完成初始化。返回 boolean。与只读属性 isInited 等价。
if (Sensorswave.isInitialized()) {
Sensorswave.trackEvent('Ready')
}
isInited
只读属性,判断 SDK 是否已完成初始化。未初始化时为 false。
if (Sensorswave.isInited) {
Sensorswave.trackEvent('Ready')
}
init(sourceToken, config?)
手动初始化 SDK(不使用 Vue 插件)。sourceToken 作为独立参数传入。
⚠️ 直接调用
init()不会注入页面生命周期 mixin,因此页面浏览 / 离开的自动采集将失效。 仅在你不需要自动页面采集、或希望完全控制初始化时机时使用。
Sensorswave.init('your_source_token', {
apiHost: 'https://example.com',
autoCapture: true,
})
destroy()
销毁 SDK 实例:停止批量发送器、销毁所有插件、移除全部事件监听器并重置为未初始化状态。销毁后可重新 init() 或再次 app.use() 安装。
Sensorswave.destroy()
自动采集事件
开启 autoCapture(默认开启)后,SDK 会根据运行平台自动注册对应采集器:
- 小程序:启动、显示 / 隐藏、页面浏览 / 离开(由全局 mixin 驱动)、(默认)分享
- App:启动 / 退出(后台满 30s 才触发
$AppEnd,30s 内回前台视为同会话)、首次安装、UTM 首值归因($UserSet)、页面浏览 / 离开(由全局 mixin 驱动) - H5:页面浏览、页面加载性能、页面离开、(可选)点击
页面浏览 / 离开采集通过 install() 注入的全局 mixin 统一驱动(onLoad / onShow / onHide / onUnload),业务页面零侵入——这是 Vue 插件的标准用法。直接调 init()(不走插件)时无 app 实例,需要改用手动集成,见上方「页面级事件接入」小节。
预置事件一览
| 事件 | 平台 | 触发时机 |
|---|---|---|
$MPLaunch |
小程序 | 启动(自动) |
$AppStart |
App | 启动 / 从后台回前台(自动;30s 内回前台不发) |
$AppInstall |
App | 首次启动(自动) |
$MPShow |
小程序 | 进入前台(自动) |
$MPHide |
小程序 | 进入后台(自动,即时上报) |
$AppEnd |
App | 进入后台满 30s(自动) |
$MPPageView |
小程序 | 页面显示(全局 mixin 自动) |
$AppPageView |
App | 页面显示(全局 mixin 自动) |
$PageView |
H5 | 页面显示(全局 mixin + vue-router 自动) |
$MPPageLeave |
小程序 | 页面离开 / 卸载(全局 mixin 自动,含 $event_duration) |
$AppPageLeave |
App | 页面离开 / 卸载(全局 mixin 自动,含 $event_duration) |
$PageLeave |
H5 | 页面离开 / 卸载(自动,含 $event_duration) |
$PageLoad |
H5 | 页面加载性能(自动) |
$WebClick |
H5 | 元素点击(需 enableClickTrack: true) |
$MPShare |
小程序 | 用户分享(自动包裹 onShareAppMessage) |
$Identify |
全部 | identify() |
$UserSet |
全部 | UTM 首值归因(每次启动 + 首次拿到非空 UTM 时自动发,含 5 个 UTM 键) |
$FeatureImpress / $ExpImpress |
全部 | A/B 曝光(自动,含 user_properties: $feature_/ $exp_ 命中赋值或未命中清空) |
预置属性
SDK 会自动采集一系列以 $ 开头的预置属性并附加到每个事件,包括:
- 设备 / 系统:
$lib(固定uniappx)、$lib_version、$model、$os、$os_version、$screen_width、$screen_height、$timezone_offset、$language - 小程序特有:
$brand、$manufacturer、$network_type、$scene - App 特有:
$brand、$manufacturer、$device_id、$wifi、$app_version、$app_id、$app_name、$region、$network_type - H5 特有:
$browser、$browser_version、$viewport_width、$viewport_height - 页面信息:
$url、$url_path、$url_query、$title、$referrer(H5 另有$host、$pathname、$referrer_host、$search_engine) - UTM 渠道:
utm_source、utm_medium、utm_campaign、utm_content、utm_term
⚠️
$前缀为系统保留,自定义事件属性请勿使用$前缀,以免与预置属性冲突。
数据安全
- 自定义事件属性脱敏:
token、password、secret、cookie、session_id、api_key等 17 类敏感关键词命中的字段,其值在发送前自动掩码为***(保留键名,仅丢弃值)。 - URL 查询参数脱敏:
$url_query中的敏感参数会被整体剔除。
鸿蒙适配
App 鸿蒙端需要声明网络与网络信息相关权限,否则事件数据无法上报、$network_type 等属性无法正常采集:
// entry/src/main/module.json5
{
"module": {
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" },
{ "name": "ohos.permission.GET_NETWORK_INFO" }
]
}
}
⚠️ 关键说明:必须配置
ohos.permission.GET_NETWORK_INFO权限才能正确获取网络信息鸿蒙平台上,SDK 通过
uni.getNetworkType()获取当前网络类型以采集$network_type预置属性。若未声明ohos.permission.GET_NETWORK_INFO权限,uni.getNetworkType()将调用失败,导致$network_type始终为空。这是鸿蒙端正确获取网络信息的前提,请务必在module.json5中声明该权限。各权限作用:
ohos.permission.INTERNET:保证事件数据能正常上报ohos.permission.GET_NETWORK_INFO:保证$network_type能正确获取
自定义基座与真机调试说明
uni-app x 的 iOS 端业务层(uvue / uts)始终运行在 JS 引擎上,uts 插件的原生实现只有打进自定义基座(或正式包)才会被编译生效。这决定了各功能在不同运行环境下的可用性:
| 功能 | iOS 标准基座(开发运行) | iOS 自定义基座·模拟器 | iOS 自定义基座·真机 / 正式包 | Android / 鸿蒙(任意运行) |
|---|---|---|---|---|
基础埋点(预置事件 / trackEvent / 用户体系 / A/B / UTM / 公共属性) |
✅ | ✅ | ✅ | ✅ |
trackException 手动上报 |
✅ | ✅ | ✅ | ✅ |
| error 级异常自动采集 | ❌(iOS 无 JS 级捕获面) | ❌ | ❌ | ✅(仅鸿蒙有捕获面) |
| fatal 级崩溃采集(iOS) | ❌ 静默降级 | ⚠️ 仅「模拟派发」链路 | ✅ 完整链路 | —— |
| fatal 级崩溃采集(Android / 鸿蒙) | —— | —— | —— | ✅ 开发运行即可用 |
结论:只有 iOS 的 fatal 崩溃采集链路依赖自定义基座;其中「真实 NSException 派发」的验证还必须真机(模拟器可用模拟派发验证全链,见下)。 Android(Thread.setDefaultUncaughtExceptionHandler)与鸿蒙(errorManager + hiAppEvent)的崩溃采集走 JS 侧可直接编译的通道,开发运行即可验证;鸿蒙的 error 级 / fatal 级双通道同理。
iOS fatal 崩溃采集的接入步骤
iOS 端崩溃捕获需要原生钩子(NSSetUncaughtExceptionHandler),而主插件必须保留 JS 实现(标准基座可用性前提),其原生实现无法进基座——因此 iOS 崩溃捕获链承载在配套原生插件 sw-ios-crash-trigger 中(app-ios-only,无 JS 实现),由它负责崩溃钩子安装、崩溃线程落盘与记录读取;主 SDK 启动时经原生代理拉取记录并补发,业务侧零额外代码。
- 将配套插件
sw-ios-crash-trigger导入工程uni_modules/(与主 SDK 一同分发) - 初始化时开启
enableCrashTrack: true - 打自定义基座(会自动包含该插件的原生实现)
- 真机验证:触发崩溃 → 进程终止 → 重新打开应用 → 启动时补发
$Exception($exception_level = fatal)
⚠️ 未集成配套插件(或标准基座运行)时,iOS fatal 链路静默降级:SDK 其余功能完全不受影响,仅崩溃不落盘、无补发。
许可
Apache-2.0

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 4
赞赏 0
下载 12586883
赞赏 1949
赞赏
京公网安备:11010802035340号