一文看懂:小程序分享到朋友圈

背景

近日小程序支持分享到朋友圈的消息可以说是小程序开发圈的一个重磅炸弹,转转小程序团队也在收到微信邀请后第一时间进行了调研,并对转转小程序迅速进行了能力支持,本文将全面解读微信此项能力。

概述

此项能力其实分成两个模块:

1、小程序分享到朋友圈能力

image

2、朋友圈打开小程序的能力

分享到朋友圈的样式
image

朋友圈里面打开的样式
image

开发

我们也分两个模块来看:

1、小程序分享到朋友圈能力

在小程序界面显示分享到朋友圈按钮的能力,目前要求如下:

1.安卓平台:

要求微信版本7.0.16及以上,基础库2.11.13及以上,笔者在测试中发现,此项能力也跟机型有关,目前发现OPPO一款机型无分享到朋友圈按钮,小米机型均有此项能力。

2.IOS平台:

目前还不支持此项能力,但高版本微信支持朋友圈打开小程序能力(下文述)

小程序页面默认不开启分享到朋友圈按钮,除非代码中主动设置:

1.页面需设置允许“发送给朋友”,代码示例:

onShareAppMessage() {    
  return {      
      title: '买卖二手,省钱又赚钱!转转,一个帮你赚钱的网站!',
      path: '/pages/index/index',
      imageUrl:'https://pic5.zhuanstatic.com/zhuanzh/n_v2be00a9c4aa4941bf8567f5fd999e2709.png',
   }
}

2.页面需设置允许“分享到朋友圈”,代码示例:

onShareTimeline() {
  return {
    title: '[小程序] 买卖二手,省钱又赚钱!转转,一个帮你赚钱的网站!',
    query: 'zzfrom=pyq'
  }
}

3.开启分享菜单中的“分享到朋友圈”按钮:

wx.showShareMenu({
      withShareTicket: true,
      menus: ['shareAppMessage', 'shareTimeline']
})

这项要求微信在文档中并没有提到,但实测发现必须调用此方法才能出现分享到朋友圈按钮,可以在onLoad生命周期调用此方法

其中:

1.最新版微信开发者工具支持此项能力的模拟调试

2.存在 web-view 组件的页面不支持发起分享

3.onShareTimeline是自基础库2.11.3开始新增的页面生命周期,行为与onShareAppMessage类似

4.该生命周期需返回Object,用于自定义分享内容,其中:

  • title:分享标题,默认去小程序名称
  • query:分享出去的页面上携带的参数,用于标示渠道来源等
  • imageUrl:分享图片,默认使用小程序logo

5.特别强调:分享到朋友圈不支持path参数,也就是说用户在哪个页面发起分享,分享出去的就是哪个页面,这就要求开发者对分享页面进行一些适配,因为我们分享到朋友圈的页面,用户打开时会进入一个“单页模式”,在此模式下,很多sdk无法使用。

2、朋友圈打开小程序的能力

用户在朋友圈打开分享的小程序页面,并不会真正打开小程序,而是进入一个原本页面的“单页模式”的页面,上文提到,用户分享的原始页面和朋友圈打开的“单页模式”页面,其实对开发者来讲是同一个页面,为了区分,微信给出了两个新的场景值:

1154:朋友圈打开小程序,也就是正处在“单页模式”,开发者可以根据这个场景值进行适配,理论上除此场景值外,都是正常模式。

1155:从“单页模式”进入正常模式,由于此项行为是微信统一行为,开发者无法进行标记,如果想对此项行为进行统计,可以使用该场景值。

“单页模式”需要适配什么呢?

微信官方对“单页模式”有以下解释:

1.“单页模式”下,页面顶部固定有导航栏,标题显示为分享时的标题。底部固定有操作栏,点击操作栏的“前往小程序”可打开小程序的当前页面。顶部导航栏与底部操作栏均不支持自定义样式。

样式参考下图

image

这两处的样式是无法自定义的。

其中,用户只能通过下方“前往小程序”按钮进入正常模式。

如果小程序使用了自定义导航头部,则需要进行一定的适配,比如我司小程序,顶部使用了自定义背景,适配前是这样:

image

由于顶部title栏微信有固定样式,因此我们在头部加了一个灰色背景进行遮挡。

image

2.“单页模式”默认运行的是小程序页面内容,但由于页面固定有顶部导航栏与底部操作栏,很可能会影响小程序页面的布局。因此,请开发者特别注意适配“单页模式”的页面交互,以实现流畅完整的交互体验。

在app.json中新增了对单页模式的配置项:

"singlePage" : {  "navigationBarFit" : "" //float或squeezed}

该项配置可以设置顶部默认title栏的表现,其中:

默认值:

  • 如果页面使用了自定义导航栏模式,则此项默认为:float,意为导航栏浮在页面上,不对原本页面布局产生影响(但可能遮挡原本页面部分元素)
  • 如果否则默认为:squeezed,表示页面被导航栏挤压,与页面不相交,也就是在页面顶部留出固定空间放微信的导航栏,原本页面将往下移动

当然这两个值也可以根据页面需要而设置不同值。

还有一点需要注意:

单页模式下,wx.getSystemInfo 接口返回的 safeArea 为整个屏幕空间,例如:

在iPhone6下,屏幕尺寸为375x667

  • 在单页模式下,safeArea的高度为:667
  • 在正常模式下,safeArea的高度为:647

如果有依赖safeArea布局的页面需要进行适配。

3.“单页模式”下,一些组件或接口存在一定限制

这一点是单页模式适配最麻烦的地方,我们先看哪些组件和接口无法使用

可跳过直接看下面总结

分类 功能点
组件 button open-type 、 camera 、 editor 、 form 、 functional-page-navigator 、 live-pusher 、 navigator 、 navigation-bar 、 official-account 、 open-data 、 web-view
路由 wx.redirectTo 、 wx.reLaunch 、 wx.navigateTo 、 wx.switchTab 、 wx.navigateBack
界面 导航栏 、 Tab Bar
网络 mDNS 、 UDP 通信
界面 导航栏 、 Tab Bar
数据缓存 周期性更新
媒体 VoIP 、 wx.chooseMedia 、 wx.chooseImage 、 wx.saveImageToPhotosAlbum 、 wx.chooseVideo 、 wx.saveVideoToPhotosAlbum 、 wx.getVideoInfo 、 wx.compressVideo
位置 wx.openLocation 、 wx.chooseLocation 、 wx.startLocationUpdateBackground 、 wx.startLocationUpdate
转发 wx.getShareInfo 、 wx.showShareMenu 、 wx.hideShareMenu 、 wx.updateShareMenu
文件 wx.openDocument
开放接口 登录 、 小程序跳转 、 用户信息 、 支付 、 授权 、 设置 、 收货地址 、 卡券 、 发票 、 生物认证 、 微信运动 、 微信红包
设备 蓝牙 、 iBeacon 、 Wi-Fi 、 NFC 、 联系人 、 剪贴板 、 电话 、 扫码
广告 ad 、 wx.createRewardedVideoAd 、 wx.createInterstitialAd

在单页模式下禁用的能力非常多,我们可以理解为:单页模式下仅允许内容展示和UI交互,不允许任何互动或操作

其中,给我们影响最大的有:

  • 登录

在单页模式下调用wx.login将不会成功,也就是说我们的页面需要支持非登录态下的展示(即便是静默登录也不支持)

对此,转转小程序在改造时比较简单:

if(this.scene == 1154) {  this.$httpWithLogin = this.$http}

即直接在单页模式下,将所有接口请求方法改写为无需登录态的请求方式。

对于此项限制,不同的小程序页面需要进行针对性处理。

  • 跳转

单页模式下,不支持任何页面跳转方法,也就是说,用户无法离开当前页,除非点击“前往小程序”按钮,回到正常模式。

  • 其他

微信提供此项能力的初衷就是希望能在朋友圈展示更多内容,而不希望用户直接进入小程序,但单页模式下的限制太多了,无法一一进行改造,笔者的建议是,解决阻碍页面正常显示的问题和阻碍核心页面流程的问题即可,在使用不支持的能力时,微信会进行如下处理:

  1. 如果用户有点击行为,则微信会统一toast:‘请前往小程序使用完整服务’

  2. 如果没有点击行为,该方法会进入调用失败逻辑:

image
  • 注意:
  1. 在单页模式下,依然支持不离开页面的各种交互,比如tab、幻灯片等
  2. 在单页模式下,只有底部“前往小程序”按钮可以进入到正常小程序
  3. 在单页模式下,支持再次被分享到朋友圈,也支持发送给朋友(同小程序卡片,打开会进入正常小程序)
  4. 云开发资源需开启未登录访问方可在单页模式下使用:

默认情况下云开发资源不允许未登录访问,需要在云控制台 - 设置 - 全局设置中手动为云环境开启允许未登录访问。

并且在未登录模式下,C 端权限控制必须使用安全规则,即云函数、数据库和文件存储的访问都必须通过安全规则,因此控制台设置时除了开启允许未登录访问云环境外,还必须在云函数、数据库和文件存储分别的权限设置中选择安全规则并配置。未登录用户访问时,安全规则的 auth 字段为空,可以此判断请求来自未登录用户的访问。

  1. 不允许横屏使用
  2. 若页面包含 tabBar,tabBar 不会渲染,包括自定义 tabBar
  3. 本地存储与小程序普通模式不共用,这一点决定了单页模式和正常模式,互通的唯一途径就是1155这个场景值

低版本兼容

分享到朋友圈按钮:低版本微信目前无法出现该按钮

朋友圈打开小程序:低版本微信打开朋友圈会进入一个升级提示页,不过这是一个基础库逐渐覆盖的过程,据发稿时,实测发现iOS微信7.0.14版本即可正常显示单页模式。

image

常见问题

1、按照文档设置了,但并没有出现分享到朋友圈按钮

可能的解决方案有:

  • 调用wx.showShareMenu方法开启菜单
  • 更换调试设备

2、单页模式无法正常打开

首先建议使用真机调试对单页模式进行调试

其次检查是否有关键流程被限制的sdk能力阻断

最后检查页面报错

3、shareImageMessage错误[>>>WX好像已经修复了只读属性 可以正常读取了]

image

该错误的是因为微信在单页模式下新增了一个内部方法:wx.shareImageMessage,并且微信禁止了该方法的读取/枚举权限,否则就会直接报错,社区里面很多开发者遇到了这个错误,转转小程序也遇到了,核心原因都是在于:

页面代码或者第三方框架/插件中含有对wx拷贝的操作,类似:

Object.assign({},wx)

我们需要找到此类代码并进行兼容,示例如下:

//先将报错方法设置为不可枚举for (let key in wx) {    try {      if(wx[key]) {}    }catch(e) {      Object.defineProperty(wx,key,{        enumerable:false      });    }}Object.assign({},wx)

4、缓存问题

当用户短时间内第二次进入朋友圈分享的小程序单页时,会存在一定的缓存(也可以说该单页实例还驻留在内存里):

我们定义的一些变量值被缓存下来了,但依然会触发Page的各个生命周期。

这会导致一些问题,比如我们通过一个在Page方法外的普通变量来记录页面吸顶状态:

let isSticky = falsePage({  onShow(){    //第二次进入时,isSticky == true    if(!isSticky){      //do sth      isSticky = true    }  }})

以上就是关于小程序分享到朋友圈这项能力开发上的经验和解读,期望能够帮助到各位读者朋友。

笔者看法

最后,笔者也想谈谈对这项能力的看法。

微信提供这项能力,可以解决目前小程序从朋友圈回流效果差的问题,之前小程序想分享到朋友圈,几乎唯一的方式是生成一个图片二维码并分享出去,不过以笔者经验,这种方式回流效果越来越差,这极大限制了小程序在朋友圈的传播能力,微信想解决这个问题,但又非常克制,微信不希望用户从朋友圈直接进入小程序,而是提供的单页模式,旨在期望给用户更多的内容展示,通过内容吸引用户进入小程序,虽然与我们的期待有一些落差,但这项能力确实对小程序在朋友圈的传播会有很大的促进作用,相信会有越来越多的小程序支持此项能力。

文章转自大转转FE 公众号