跳到主要内容

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.tssrc/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 只作用于该操作。