Uni-app App SDK 使用指南
听云 uni-app App SDK,适用于 uni-app App,不适用于 uni-app x。采集数据上传到听云 Web 产品。
支持页面、uni.request 网络请求、JavaScript 错误和用户操作监控,原生网络调用由对应原生 SDK 采集。Vue3 项目支持 Vue 与 nvue 页面;自动操作需要配套安装听云编译插件。Web 和小程序请使用对应平台 SDK。
uni.request 支持回调和 Promise 两种调用方式:传入函数回调时保留原 RequestTask;无函数回调时可继续使用 await、.then() 和 .catch()。
安装向导
1. 安装 SDK
在项目根目录执行:
npm install @tingyun-sdk/uniapp-app
2. 创建初始化文件
接入 SDK 时,需要考虑两点:
- 初始化顺序:静态导入的模块先于入口正文执行,直接在
main.js或main.ts顶部调用init(),可能晚于业务模块中的请求。初始化前已发生的事件无法补采。 - 配置维护:集中管理 SDK 导入、配置和初始化调用,便于查找与调整。
因此,建议将这些代码放入独立的 tingyun/init.js,TypeScript 项目使用 tingyun/init.ts,并在应用入口首先导入。初始化文件仅依赖 SDK 和必要配置,避免引入业务模块或循环依赖。
推荐位置如下:
| 项目来源 | 初始化文件 | 应用入口 |
|---|---|---|
| CLI 创建 | src/tingyun/init.js 或 src/tingyun/init.ts | src/main.js 或 src/main.ts |
| HBuilderX 创建 | tingyun/init.js 或 tingyun/init.ts | 根目录 main.js 或 main.ts |
目录结构示例(以 JavaScript 为例):
CLI 创建的项目/
├── src/
│ ├── tingyun/
│ │ └── init.js # 新建:SDK 初始化文件
│ ├── main.js
│ ├── manifest.json
│ └── pages.json
└── package.json
HBuilderX 创建的项目/
├── tingyun/
│ └── init.js # 新建:SDK 初始化文件
├── main.js
├── manifest.json
└── pages.json
CLI 项目即使在 HBuilderX 中打开,仍使用它原来的目录和编译依赖。
从听云 Web 控制台获取对应应用的数据上传地址和 token,填入初始化文件:
import Tingyun from '@tingyun-sdk/uniapp-app'
Tingyun.init({
beacon: '<包含协议的数据上传地址>',
token: '<应用 token>',
})
export default Tingyun
3. 在应用入口加载
Vue2、Vue3 项目都在 main.js 或 main.ts 顶部、在其他导入之前加入:
// #ifdef APP
import './tingyun/init'
// #endif
如有具体的条件编译需求,请参考 uni-app 官方条件编译文档。
4. 验证接入
重新运行 App,在 HBuilderX 的运行控制台或连接设备的运行日志中搜索 [tingyun-uniapp]。 出现以下日志表示 SDK 已完成初始化(时间为示例):
2026-09-16 10:00:00.000 +08:00 [tingyun-uniapp] [INFO] [init] SDK initialized
打开并切换应用页面,等待上报后,在听云 Web 控制台查看对应页面数据。已接入编译插件时,也可点击页面中已有的 @click 按钮验证用户操作采集,命名规则见编译插件文档中的“事件与操作名称”。
可选配置
Vue3 用户操作采集
uni-app Vue3 项目可采集按钮点击等用户操作,需要配合听云编译插件 @tingyun-common/vite-plugin-uniapp。该插件在构建时为页面事件补充采集信息,接入步骤见uni-app Vite 插件使用指南。
仅使用页面、请求、错误和手动操作功能时,完成 SDK 初始化即可。
SDK 配置
在初始化文件中通过 Tingyun.init() 传入配置。以下列出配置类型及默认行为:
interface InitConfig {
beacon: string // 必填,包含协议的数据上传地址
token: string // 必填,应用 token
key?: string // 应用 key
// off 关闭日志;info 基础日志(默认);debug 详细诊断日志。
logging?: { level?: 'off' | 'info' | 'debug' }
// 原生会话等待上限(毫秒),默认 5000,范围 0–10000;0 不等待。
nativeContextWaitTimeout?: number
page?: {
enabled?: boolean // 页面监控,默认 true
autoEnabled?: boolean // 自动页面监控,默认 true
}
jsError?: {
enabled?: boolean // 错误监控,默认 true
autoEnabled?: boolean // 自动错误监控,默认 true
uploadEmptyFileErrors?: boolean // 采集 无文件名错误,默认 true
}
action?: {
enabled?: boolean // 操作监控,默认 true
manualEnabled?: boolean // 手动操作,默认 true
autoEnabled?: boolean // 自动操作,默认 true
}
// 五位开关依次对应 URL、请求头、请求体、返回头、返回体,默认均关闭。
// 1 开启全量采集,0 关闭;如 '00100' 表示完整采集请求体。下方字段规则独立生效。
collect_all_param?: string
// 指定采集字段,默认空;如 [{ type: 1, key: 'orderId' }] 采集 URL 中的 orderId。
opt_custom_param_rule?: Array<{
type: 1 | 2 | 3 | 4 | 5 // 依次对应 URL、请求头、请求体、返回头、返回体
// 字段名称;URL、请求体、返回体支持嵌套路径,如 'order.type'、'items[0].id'
key: string
}>
}
原生接口正常返回但会话 ID 尚未就绪时,SDK 继续采集,暂缓自身上报,每秒尝试读取一次。取得有效会话后放行;超时使用 SDK 会话放行并停止轮询。插件缺失或首次调用异常不等待。等待配置的有限数字限制到上述范围,其他非法值使用默认值;等待队列仍受 100 条容量限制,满时丢弃新数据。详细过程可开启 debug 日志查看。
API 说明
SDK API 调用方式
SDK 初始化成功后,页面和业务模块可以通过以下三种方式调用业务 API。nvue 推荐使用公共入口;采用模块导入时,推荐导入前面创建的初始化文件。
后续各 API 示例中的 sdk 均指已判空确认可用的 uni.$tingyunApp。
方式一:通过公共入口调用(推荐)
SDK 初始化成功后提供 uni.$tingyunApp。通过该入口可直接使用已初始化的 SDK,尤其适合 nvue 页面,能减少页面产物中重复打包 SDK 的体积。
调用前必须判空:SDK 尚未初始化成功或公共入口不可用时,uni.$tingyunApp 可能为 undefined。使用 if (sdk) 或可选链 sdk?.method(),避免影响业务执行。
JavaScript 调用示例,以设置用户 ID 为例:
const sdk = uni.$tingyunApp
// 确认公共入口可用后再调用。
if (sdk) {
sdk.setUid('user-001')
}
TypeScript 调用示例,使用仅类型导入提供类型提示:
import type { TingyunApi } from '@tingyun-sdk/uniapp-app'
const sdk: TingyunApi | undefined = uni.$tingyunApp
sdk?.setUid('user-001')
方式二:导入初始化文件(推荐的模块导入方式)
导入前面创建的 tingyun/init.js 或 tingyun/init.ts,会先执行其中的初始化代码,再取得导出的 SDK。以下以设置用户 ID 为例,@ 指向项目源码目录:
import Tingyun from '@/tingyun/init'
Tingyun.setUid('user-001')
这种方式通过模块依赖保证先执行初始化。nvue 页面导入该文件可能重复打包 SDK,建议使用方式一。
方式三:直接导入 SDK 包
直接导入只取得 SDK API,不会执行项目初始化文件。使用前需确保应用入口已完成初始化,适合已有统一初始化管理的代码。调用示例:
import Tingyun from '@tingyun-sdk/uniapp-app'
Tingyun.setUid('user-001')
公共入口已初始化时,API 调用会转发到该入口,共享同一份 SDK 状态。
公开类型可从包根通过 import type 导入,包括 InitConfig、TingyunApi、操作类型、ContextMap、错误输入和页面安装类型。
手动操作:newAction
手动创建操作,记录操作耗时、执行结果及关联请求。
type ActionContextValue =
| string
| number
| boolean
| null
| ActionContextValue[]
| { [key: string]: ActionContextValue }
type ActionContext = Record<string, ActionContextValue>
interface ActionOptions {
name: string // 操作名称
op?: string // 操作类型
desc?: string // 操作描述
context?: ActionContext // 本次操作的附加信息
}
interface ActionEndOptions {
status?: 'success' | 'fail'
context?: ActionContext
}
interface ActionHandle {
readonly id: string
readonly kind: 'manual' | 'interaction'
readonly name: string
end(options?: ActionEndOptions): void
fail(options?: ActionEndOptions): void
}
declare function newAction(options: ActionOptions): ActionHandle
const action = sdk.newAction({ name: 'custom-action' })
uni.request({
url: 'https://example.com/api',
success: () => action.end(),
fail: () => action.fail(),
})
name 必填,保存后的名称至少包含一个非空白字符。名称长度上限为 1024,超长截断后参与同名判断。op、desc 为可选字符串。op、desc 和 context 均不设置长度限制。
context 顶层为普通对象,成员遵循上述递归类型。运行时同时校验有限数字、普通对象和循环引用;函数、undefined 成员、特殊对象及属性读取失败均视为非法参数。SDK 复制合法数据,后续修改原对象不会影响操作数据。
多个自动操作和不同名称的手动操作可以同时关联请求,每条操作独立结束并上报。同名手动操作在结束前保留名称,重复创建返回空句柄。创建参数非法、SDK 未初始化或手动操作采集关闭时 也返回空句柄;其 id 为空字符串,end()、fail() 可安全调用。
end() 默认成功,可通过 status 指定 success 或 fail;fail() 固定失败。结束时提供的 context 按顶层属性合并,同名属性使用新值。非法结束参数使操作保持原状态,调用方可再次传入有效参数结束。重复结束保持幂等。
操作结束后等待已关联请求完成再上报;手动操作的成功或失败由调用方指定。
手动页面监控:getPageMixin
只对接入 mixin 的页面采集页面监控数据。
interface PageMonitoringMixin {
onLoad?(query?: Record<string, string | undefined>): void
onShow?(): void
onReady?(): void
onUnload?(): void
}
declare function getPageMixin(): PageMonitoringMixin
初始化时设置 page: { enabled: true, autoEnabled: false },然后在目标页面中加入返回的 mixin:
export default {
mixins: [uni.$tingyunApp.getPageMixin()],
}
请在加载页面前完成 SDK 初始化。SDK 未初始化、页面监控关闭或自动页面监控开启时,返回空对象。hookPage() 为历史接口,自 1.1.0 起调用不产生页面监控效果。
手动错误上报:captureException
手动上报错误。自动错误采集依赖运行环境触发 uni.onError、uni.onUnhandledRejection 回调;未通过这些回调通知 SDK 的错误,可调用此 API 上报。
type ErrorDetails = (
| { message: string; stack?: string }
| { message?: string; stack: string }
) & { fileName?: string; lineNumber?: number; columnNumber?: number }
declare function captureException(
error: Error | string | ErrorDetails,
options?: { category?: 'js' | 'other' },
): string | undefined
error 可传入 Error 对象、包含 message / stack 的错误对象或错误文本。options.category 可指定 'js'(默认)或 'other'。
try {
JSON.parse('invalid JSON')
} catch (error) {
if (error instanceof Error || typeof error === 'string') {
sdk.captureException(error)
}
}
正常记录时返回字符串错误追踪 ID,未记录时返回 undefined,不表示上传成功。jsError.enabled 需开启;uploadEmptyFileErrors: false 时忽略无法解析文件名的错误。
设置用户 ID:setUid
设置业务用户 ID,将监控数据与用户关联,便于定位特定用户的问题。
declare function setUid(uid: string | number): void
sdk.setUid('user-001')
数字先转为字符串,最大长度为 50,超长截断。设置后保存到本地存储;传入空字符串可清空。无返回值。
设置与移除附加信息:setContext / removeContext
为后续上报的监控数据添加或移除自定义附加信息。
type ContextMap = Record<string, ActionContext>
declare function setContext(key: string, value: ActionContext): void
declare function setContext(contexts: ContextMap): void
declare function removeContext(key: string): void
key 为字符串名称(允许空字符串),value 为普通对象;也可用一个对象批量设置。每个命名值遵循 newAction.context 的 JSON 数据规则,字符串、数组等须放进普通对象中。
sdk.setContext('custom', { field: 'value' })
不再需要该信息时删除:
sdk.removeContext('custom')
同名对象按第一层属性浅合并。SDK 在设置时复制合法上下文,后续修改输入不影响已保存数据。非法命名值保留旧值,并停止本次调用;批量中此前成功的项仍生效。JavaScript 调用传入的 null、undefined 命名值会被忽略,删除请用 removeContext()。
信息仅保留在当前运行期间,组包时读取当前值;两个方法均无返回值。手动操作的 context 只作用于该操作。