uni-app:APP/IOS/小程序对接数商云

背景

我们的公司需要给APP、IOS、小程序对接数商云,而我们的这个几个产品都是通过uni-app去开发的,比较特殊的一点是,我们公司没有专门的原生工程师,因此对接这3个产品的责任就交给了我这个前端去负责。

对接方案

接到这个任务的时候,我首先做的是阅读数商云的文档,数商云提供了以下几种接入方式:小程序SDK、JS SDK、IOS_SDK以及Android_SDK。小程序使用小程序SDK接入就好了,没有问题。问题在于app和ios要如何接入,采用原生的方案对接我一个前端难度很大啊?我想到以前好像看到过说APP/ios是可以通过小程序SDK进行对接的,因此我决定APP和ios也采用小程序SDK去进行对接。
最终我们的项目也是按照此方案进行对接的,也许可以给有类似需求的人们一点启发。

多端产品均采用小程序SDK对接的好处是:

  • 对接的方式对前端更为友好
  • 小程序、app、ios可以采用同一套方案进行对接

但与此同时也存在一些问题:

  • 都采用了小程序SDK导致,无法直接通过数商云判断平台来源(当然也有相应的解决方案,后面会提及)

说干就干,我按照文档安装插件npm install --save shushangyun-masdk,这时我发现小程序原生和UNI-APP项目还是有区别啊,接入方案生搬硬套文档是行不通的。
大致存在这几个问题:

  • uni-app不支持小程序的npm构建
  • uni-app的语法和小程序不尽相同

通过观察,比较,我发现它npm构建的内容其实就是node_modules\shushangyun-masdk\miniprogram_dist

现在,我要做的就是要在uni-app引入这个SDK里面的原生自定义组件。通过查阅文档,确定了 [^1]

uni-app 支持在 App 和 小程序 中使用小程序自定义组件。

参考了以下文档:uni-app使用小程序原生自定义组件

在根目录新建wxcomponents文件夹(注意必须要叫这个名字),将npm install --save shushangyun-masdk下载下来的node_modules\shushangyun-masdk\miniprogram_dist这个文件夹里的文件复制到新建的文件夹中,结构类似以下这样:

├─pages
│  └─index
├─static
└─wxcomponents
    └─components

接着全局注册组件:

// pages.json
{
  "pages": [
    //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "uni-app"
      }
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8",
    // 注册全局组件
    "usingComponents": {
      "banner": "/wxcomponents/components/banner",
      "trigger": "/wxcomponents/components/trigger"
    }
  }
}

这时已经引入了原生组件了,但是我们还需要引入数商云的页面,这时,就不能直接引入了,还好在看过代码后,我发现这个page页面比较简单,因此我决定将它转换为普通的.vue页面,新建/pages/webview/index.vue。

// /pages/webview/index.vue
<template>
  <web-view :src="path"></web-view>
</template>

<script>
export default {
  data () {
    return {
      path: ''
    }
  },
  onLoad (options) {
    let webview = options.webview;
    console.log(webview);
    let url = decodeURIComponent(unescape(webview));
    this.path = url
  }
}
</script>

<style lang="scss" scoped>
</style>

修改pages.json文件

{
  "pages": [
    //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "uni-app"
      }
    },
    {
      "path": "pages/webview/index"
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8",
    "usingComponents": {
      "banner": "/wxcomponents/components/banner",
      "trigger": "/wxcomponents/components/trigger"
    }
  }
}

现在,可以试着去初始化一下SDK了。
配置App.vue,这里和文档一样,为了方便,直接在启动时就进行上传用户信息,正式使用时应该在登录用户(获取到用户信息)时使用

<script>
const masdk = require('./wxcomponents/index');
export default {
  onLaunch: function () {
    this.masdkInit()
  },
  methods: {
    // 初始化数商云sdk
    masdkInit () {
      //初始化sdk,应该在小程序打开的时候就初始化。
      masdk.init({
        appKey: "应用key",//应用key,必填
        appSecret: "应用secret",//应用secret,必填
        debug: fasle,//是否开启debug模式,选填,默认为fasle
        domain: '服务器地址',//服务器地址,一般不用配置此项,此项只针对私有化部署客户 
        webviewUrl: '/pages/webview/index',//用来打开活动的页面,选填,默认值是组件提供的webview页面:miniprogram_npm/shushangyun-masdk/pages/webview,如果有需要,此项指针对需要使用自己定义的页面去打开活动的开发者
      })
	  //登录一个测试用户
      //上传用户信息,这个方法应该在用户登录之后调用,此例子直接在onLaunch方法里调用了。正式使用时应该在登录用户(获取到用户信息)时使用
      masdk.infosUser({
        userid: "user12345",
        sex: "男",
        province: "广东省",
        //具体字段以商家自定义的用户表决定。
      });
    },
  },
}
</script>

<style>
/*每个页面公共css */
</style>

同时在需要的地方引入组件

// 根据业务需要使用组件的地方
<template>
  <view>
    <button size="mini"
            type="primary"
            plain="true"
            @click="triggerDemo">触发Demo</button>
    <!--引入这个trigger组件显示触发图标-->
    <trigger :param="param" />
    <!-- 数商云后台设置的key -->
    <banner position-key="后台设置的key"
            :swiper-options="swiperOptoins"
            default-image="/static/img/image/bg.png" />
  </view>
</template>

<script>
const masdk = require('../../wxcomponents/index');
export default {
  data () {
    return {
      param: {}, //数商云触发返回的数据
      swiperOptoins: { //投放组件轮播图的配置,配置项请参考小程序的swiper组件
        indicatorDots: true,
        displayMultipleItems: 1
      }
    }
  },
  methods: {
    triggerDemo () {
      //调用sdk的trigger方法
      let infosUser = uni.getStorageSync('infosUser')
      try {
        infosUser = JSON.parse(infosUser)
        if (infosUser && infosUser.userid) {
          masdk.trigger({
            userid: infosUser.userid, //触发用户id
            eventKey: '事件key', // 事件key
            conditions: {
              loginFrequency: 20,
              loginTime: '2019-10-28 08:00:00',
              registrationTime: '2019-10-01 08:00:00',
              storeConsumption: 10000
            }
          }).then((res) => {
            this.param = res.data
          })
            .catch((err) => {
              console.log(err);

            })
        }
      } catch (error) {

      }
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

这时运行uni-app项目是会报错的,因为数商云的组件引入SDK的路径是错误的。例如:

// /wxcomponents/components/banner.js
// 原始代码是这样的,现在没有用到npm安装依赖,自然不应该这样引入,事实上,好像安装了依赖好像也是引入不了的,我记得当时我是npm安装了的,但是一样会报错
const masdk = require('shushangyun-masdk');

需要改成这样:

// /wxcomponents/components/banner.js 以及 /wxcomponents/components/trigger.js
const masdk = require('../index');

当时的我是这样做的,但是发现还是有报错,Cannot read property 'appKey' of undefined。这个问题我排查了很久,对比了原生小程序接入SDK,以及debugger,发现正常情况下,小程序组件引入的masdk对象里是会带有初始化时传入的配置信息的,但是uni-app这个项目里的原生组件里的masdk (如: /wxcomponents/components/banner.js 以及 /wxcomponents/components/trigger.js里引入了masdk),里面masdk对象没有初始化到。原因我也不确定,可能是跨模块通信有问题?毕竟本来uni-app是用vue的,引入原生组件,相互通信间可能有一些兼容问题吧。

现在,我遇到的问题是,数商云的对象masdk无法在小程序自定义组件和普通的uni-app页面公用,因此我决定将这个对象存入全局对象globalData中,以解决通信的问题。

 // App.vue
 globalData: {
   // 一般的全局变量使用vuex实现,现在我遇到一个问题,数商云对象masdk无法在小程序自定义组件和普通页面公用,因此采用此种方式实现
   masdk
 },

同时,自定义的小程序组件也使用globalData的masdk。

// /wxcomponents/components/banner.js 以及 /wxcomponents/components/trigger.js
const masdk = getApp().globalData.masdk;

这时应该就可以调通数商云了,接下来就是根据业务需要进行埋点了。

关于埋点

由于本人即将离职,因此后续的埋点工作我是转交给了同事去进行的。虽然没有直接参与,有些东西还是可以聊聊的。
由于我这个方案,只用了小程序SDK去进行对接,数商云无法直接判断平台来源。
为此我需要传一个条件去标明用户触发的平台是小程序、app、ios。
另外,由于运营那边希望用户不登录也可以触发数商云,因此userid定义了一个特殊的游客id,这个时候,为了让数商云可以方便判断用户是否游客,需要传一个条件去标明用户是否已登录。
大致就是这样,后面如果有需要补充的,我也会继续更新文章。

本文目的

写这篇博客是因为替公司面试前端时,发现一个前端简历上的博客竟然有好几页那么多,想到自己博客里的寥寥几篇文章,心里难免有点波动。又发现自己的github上竟然在别人提了issues两个多月后才看到,心里还是很惊讶的。
工作越来越忙,半年007,挤占了我大部分的时间,连生活的节奏都被打乱,很多希望自己养成的习惯都被放下了。那个面试的前端,她的博客我看了一下,每篇都不是很长,但一直都在坚持,我也想试着实践一下,记录一下自己的一些小小的收获,小小的心得。

参考:
[1]: https://uniapp.dcloud.io/frame?id=%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%BB%84%E4%BB%B6%E6%94%AF%E6%8C%81

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值