手工埋点统计

智能小程序为您提供了自定义事件埋点方式之外,为满足您不同的需求,还为您提供了以下方法进行埋点。

UV的统计逻辑

利用注册回调函数的方式,优先运行AppOnLaunch和AppOnshow的生命周期中的逻辑,再运行Page的生命周期的逻辑。 优点: 1、避免框架app级别的onShow和page级别onShow的不可控时序性问题(将在 10.13 修复); 2、确保异步回调可控。

在app.js中,统计UV:

  1. App({
  2. onShow: function () {
  3. swan.request({
  4. url: 'test.php', //仅为示例,并非真实的接口地址。
  5. data: {
  6. uid: self.globalData.uuid
  7. // that.globalData.uuid为用户的唯一标识,详见"uuid的统计逻辑"。
  8. },
  9. success: res => {
  10. self.globalData.data = res.data;
  11. // 此处为网络请求,加入 callback 确保在 Page.onLoad 之前返回。
  12. self.globalData.callBackArr.forEach(callBack => {
  13. // 此处遍历执行Page级生命周期的注册的App回调函数。
  14. callBack();
  15. });
  16. }
  17. })
  18. },
  19. onHide() {
  20. if (!that.globalData.uuid) {
  21. // app的onShow丢失(ios和安卓预计在10.13修复),需重新执行一遍UV统计的逻辑。
  22. }
  23. }
  24. globalData: {
  25. data: ''
  26. // 定义一个绑定回调函数队列。
  27. callBackArr: []
  28. }
  29. });

在 index.js 中,获取应用实例:

  1. const app = getApp();
  2. Page({
  3. data: {
  4. ...
  5. },
  6. onLoad: function () {
  7. app.onLoadCallback = data => {
  8. if (data != '') {
  9. that.setData({
  10. ...
  11. });
  12. }
  13. }
  14. app.globalData.callBackArr.push(app.onLoadCallback);
  15. },
  16. onShow: function () {
  17. //判断是用户是否绑定。
  18. if (app.globalData.data && app.globalData.data != '') {
  19. that.setData({
  20. ...
  21. });
  22. } else {
  23. // getUserInfo 为网络请求,加入 callback,确保在 Page.onLoad 之前返回。
  24. app.swanCallback = data => {
  25. if (data != '') {
  26. that.setData({
  27. ...
  28. });
  29. }
  30. }
  31. app.globalData.callBackArr.push(app.swanCallback);
  32. }
  33. }
  34. })

用户唯一标识

uuid 是用户唯一标识,使用示例中提供的方法,生成uuid作为用户唯一标识的统一策略,每次进入到小程序后进行一次有效的存储,在统计中直接取出使用。 代码示例

  1. App({
  2. onShow() {
  3. const uuid = that.getUUID();
  4. that.globalData.uuid = uuid;
  5. },
  6. getUUID() {
  7. let uuid = swan.getStorageSync('uuid');
  8. if (uuid && uuid.length === 36) {
  9. return uuid;
  10. }
  11. uuid = ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
  12. (c ^ that.unit8() & 15 >> c / 4).toString(16)
  13. );
  14. swan.setStorageSync('uuid', uuid);
  15. return uuid;
  16. },
  17. // 兼容crypto.getRandomValues的callBack。
  18. unit8() {
  19. const unitCode = ((typeof crypto !== 'undefined') && crypto.getRandomValues)
  20. ? crypto.getRandomValues(new Uint8Array(1))[0]
  21. : Math.floor(Math.random() * 0xff);
  22. return unitCode;
  23. },
  24. globalData: {
  25. uuid: ''
  26. }
  27. });

PV的统计逻辑。

在Page的onShow生命周期中统计PV: 1.全局和统计相关的请求逻辑全部都放到队列的数据结构里; 2.利用队列的方式保证异步的执行顺序; 3.在相关Page页面的onShow里进行统计PV,每次onShow都做+1的操作。

  1. Page({
  2. onShow(options) {
  3. swan.request({
  4. url: 'https://host/path?query',
  5. data: {
  6. // 上报PV,做+1的操作
  7. ...
  8. }
  9. });
  10. }
  11. });

全局变量的统计逻辑

关于场景值、path、query 等不受前后台切换而改变逻辑的全局变量,统一借助 App 的 onShow 中 options 参数的 scene、path、query 等属性进行逻辑处理。

  1. /* globals Page */
  2. App({
  3. onShow(options) {
  4. if (options.scene === that.globalData.scene) {
  5. return;
  6. }
  7. that.globalData.scene = options.scene;
  8. },
  9. globalData: {
  10. scene: ''
  11. }
  12. });

options结构如下:

  1. options: {
  2. path: 'pages/index/index',
  3. query: {
  4. name: 'xx',
  5. sex: 'm'
  6. },
  7. ...
  8. }

Page级别的query在onLoad生命周期可以获取到query。

  1. // pages/index/index
  2. Page({
  3. // 触发跳转事件
  4. redirect() {
  5. swan.redirectTo({
  6. url: '../logs/logs?tel=156xxxxx333&name=xx',
  7. })
  8. }
  9. });
  10. // pages/logs/logs
  11. Page({
  12. // 触发跳转事件
  13. onLoad(options) {
  14. // options->{tel: '156xxxxx333', name: 'xx'}
  15. }
  16. });

启动次数的统计逻辑

利用session机制来统计启动次数: 1.通过 App 的 onShow 获取 appKey; 2.生成一个 session,策略“appKey + uuid + timestamp”; 3.访问开始即启动小程序,访问结束结分为:进入后台超过5min、在前台无任何操作超过30min、在新的来源打开小程序; 4.访问结束时(在触发onHide生命周期,或者满足上述条件)上报一条数据。

  1. App({
  2. onShow(options) {
  3. that.globalData.appKey = options.referrerInfo.appId;
  4. },
  5. onHide(options) {
  6. // 访问结束,上报埋点。
  7. swan.request({
  8. url: 'https://host/path:port?query',
  9. data: {
  10. session: self.globalData.uuid + self.globalData.appKey + Date.now()
  11. }
  12. });
  13. },
  14. globalData: {
  15. // 此uuid是之前通过uuid方案生成的用户唯一标识。
  16. uuid: '',
  17. appKey: ''
  18. }
  19. });