React Native
这是纯 JavaScript 桥,转发到 @webcount/app-sdk 核心,不依赖原生模块。
安装
包在 packages/react-native,要求 react-native 0.72 或更高。它是仓库里的源码包,按工作区或本地路径依赖这个目录,然后:
import { WebCount } from '@webcount/react-native';初始化
import AsyncStorage from '@react-native-async-storage/async-storage';
import { AppState, Dimensions, Platform } from 'react-native';
WebCount.preInit(
{ siteKey: 'YOUR_SITE_KEY', endpoint: 'https://YOUR_ORIGIN', appId: 'com.example.app' },
{ asyncStorage: AsyncStorage, appState: AppState, platform: Platform, dimensions: Dimensions },
);
await WebCount.init();第二个参数是宿主对象,SDK 不会自己引入 react-native。不传 asyncStorage 时队列只在内存里;不传 appState 时前后台不会自动记;不传 platform 时平台按 Android 上报。appId 与 iOS、Android 上登记的应用标识一致。region: 'cn' 时同意后再 init,并调用 grantConsent(['analytics'])。未先 preInit 就调用 track 会抛出 WebCount.preInit() first。
页面浏览
把导航状态交给 navigationHook,最内层路由名变化时发送一次 $screen_view,与上一次同名则不重复发:
<NavigationContainer onStateChange={WebCount.navigationHook} />不走 React Navigation 容器时,手写 WebCount.trackScreen('Home')。
事件
WebCount.track('purchase', { revenue: 19.9 });身份
WebCount.login(userId, { plan: 'pro' }, { type: 'login' });
WebCount.logout();type 可以是 login、email、mobile、openid、unionid 或 custom,邮箱和手机号由核心先做哈希。见 身份关联。
限制
| 项目 | 要求 | 说明 |
|---|---|---|
| 运行时 | 0.72 起 | 写在包的 peer 依赖里 |
| 页面事件 | 导航钩子 | 不接钩子就不会自动发屏幕 |
| 队列 | 传入 AsyncStorage | 有它才持久化,上限、退避和远程配置随核心 |
错误
应用标识未登记时事件被丢弃,调用不会抛出网络错误。navigationHook 拿到的状态没有路由名时直接返回,页面报表保持空白。停止与恢复采集用 optOut 和 optIn。队列上限、退避和远程配置见 SDK 总览与支持矩阵。
Flutter
插件通过 MethodChannel('webcount') 转发,采集能力等于所调用的原生 SDK。
安装
源码在 packages/webcount_flutter,要求 Dart 3 与 Flutter 3.10。仓库没有可直接 pub add 的发布记录,在 pubspec.yaml 里用路径依赖指向这个目录。iOS 工程还要链上 packages/ios 的 WebCount,Android 工程还要编入 packages/android 的 com.webcount。缺了原生类,通道调用没有接收端。
初始化
await WebCount.preInit(WebCountConfig(
siteKey: 'YOUR_SITE_KEY',
endpoint: 'https://YOUR_ORIGIN',
appId: 'com.example.app',
));
await WebCount.init();appId 与原生端登记的应用标识一致。region: 'cn' 时同意后再 init,并调用 grantConsent(['analytics'])。插件不转发生命周期:iOS 由原生 SDK 自动记启动和前后台;Android 需要在原生代码里调用 WebCount.onLaunch、onShow、onHide,见 Android。
页面浏览
给 MaterialApp 挂上观察者:
MaterialApp(navigatorObservers: [WebCount.navigatorObserver]);观察者在 didPush、didReplace 和 didPop 时取路由的 settings.name,无名路由不发,与上一次同名也不再发。也可以手写 WebCount.trackScreen('Home')。
事件
await WebCount.track('purchase', {'revenue': 19.9});身份
await WebCount.login('USER_ID');
await WebCount.logout();type 是命名参数,默认 'login',邮箱或手机号要显式传 type: 'email' 或 type: 'mobile'。原生端这一版把 setProps 记成事件公共属性。见 身份关联。
限制
| 项目 | 要求 | 说明 |
|---|---|---|
| 原生库 | 必须同时编入 | 插件自己不包含采集核心 |
| 路由名 | 需要 settings.name | 无名路由不会发屏幕 |
| 队列 | 随原生端 | Android 与 iOS 这一版只有内存队列,flush 只是转给原生端 |
错误
原生类缺失时,通道调用失败,Dart 侧会收到平台异常,而不是一条静默的统计错误。应用标识未登记时事件被丢弃。页面报表为空时先看 RouteSettings.name。原生这一版没有持久队列,进程结束前未发出的事件会丢失。见 iOS。
uni-app
H5 目标检测到后会直接抛错,请改放 w.js,见 JavaScript(w.js)。
安装
包在 packages/uni-app,按工作区依赖引用。仓库没有公开发布的安装命令。按目标自动分流用包根:
import { WebCount } from '@webcount/uni-app';@webcount/uni-app/mp 与 @webcount/uni-app/app 只导出对应核心的 createWebCount(adapters),不带分流逻辑。
初始化
preInit 第二个参数是适配器,不传会抛错。小程序目标可用 @webcount/miniprogram 导出的 mpAdapters 生成;App 目标要自己实现。
const core = WebCount.preInit(
{
siteKey: 'YOUR_SITE_KEY',
endpoint: 'https://YOUR_ORIGIN',
appId: 'YOUR_APPID',
},
adapters,
);
core.init();preInit 返回选中的核心,之后也可以从 WebCount.core 取。目标按 target 参数、UNI_PLATFORM 环境变量、uni.getSystemInfoSync() 的顺序判断,结果在 WebCount.detect。appId 按目标登记为小程序 appid 或应用标识。region: 'cn' 时同意后再调用 init,并调用 grantConsent(['analytics'])。
页面浏览
小程序目标沿用页面生命周期,进入和离开会发浏览。App 目标需要 trackScreen,或由适配层交页面生命周期。H5 的浏览由 w.js 发送。
事件
WebCount.core.track('purchase', { revenue: 19.9 });身份
在核心上调用 login 与 logout,参数与小程序或应用核心一致。项目不在识别模式时 login 被忽略。见 身份关联。
限制
| 项目 | 行为 | 说明 |
|---|---|---|
| H5 | 不走此包 | 检测为 H5 时会抛错 |
| 适配器 | 调用前传入 | 否则无法选择核心 |
| 点击 | 默认关闭 | preInit 把 autoTrack 设为 false,除非你传入 true |
错误
H5 编译调用 preInit 会失败,应改用 w.js。不传适配器时抛出 uni-app: pass adapters or use /mp / /app entries in the host。应用标识未登记时事件被丢弃。小程序目标的队列、退避与微信入口相同;App 目标用 @webcount/app-sdk 核心,持久队列取决于你的存储适配器。小程序目标到小程序实时页看启动记录,App 目标到应用实时页看。见 SDK 总览与支持矩阵。