热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Hybrid容器设计之第三方网站

平台化容器API释放接上文:(阅读本文前,建议阅读前三篇文章先)浅谈Hybrid技术的设计与实现浅谈Hybrid技术的设计与实现第二弹浅谈Hybrid技术的设计与实现第三弹——

平台化容器API释放

接上文:(阅读本文前,建议阅读前三篇文章先)

浅谈Hybrid技术的设计与实现

浅谈Hybrid技术的设计与实现第二弹

浅谈Hybrid技术的设计与实现第三弹——落地篇

之前设计Hybrid整块交互的时候,受众都是自己的团队,没有想往“公司化”和“平台化”方向发展,而近期业务的发展逐渐超出预期了,慢慢会有第三方网站接入我们的APP,而且第三方网站还会用一些Native的能力,这个时候之前的使用似乎就不太合适了,所谓JS-SDK就需要存在了。

类似这种需求,做的最完善的当属微信的native容器了,微信这种属于海量容器,对所有的接入方基本一视同仁,就算内部团队会有一些“特权”能力,使用方式与第三方接入都是一套体系,可能只是文档有所不同罢了。微信容器中,最常用的端能力要属:

① 统一登录,获取微信的登录态&使用微信登录,微信方给予第三方应用有限的用户信息(非JS-SDK)

② 分享接口

③ 微信支付

我们今天以微信(中间可能参考其他APP平台)为范本,思考下我们自己的容器如何处理第三方的情况。

我们做这块设计之前,首先需要明确一个定位:

我们的Native容器,应该给第三方网站提供哪些能力?

如果不加限制的提供能力,就属于“内部”项目了,如微信容器一般,对外提供的能力屈指可数,这里是我们一个比较常见的第三方容器:

wx.openApp(appid);

这里的实现方案可以是这样,一般来说,我们对外释放的接口都是比较通用的,像一些私密的接口才会有白名单维护,比如我们自己的app对应的几个图片操作接口:

 1 //选取图片接口
2 wx.chooseImage({
3 count: 1, // 默认9
4 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
5 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
6 success: function (res) {
7 var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
8 }
9 });
10 //上传图片接口
11 wx.uploadImage({
12 localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得
13 isShowProgressTips: 1, // 默认为1,显示进度提示
14 success: function (res) {
15 var serverId = res.serverId; // 返回图片的服务器端ID
16 }
17 });
18 //预览图片接口
19 wx.previewImage({
20 current: '', // 当前显示图片的http链接
21 urls: [] // 需要预览的图片http链接列表
22 });

其中预览我把他作为私密接口不予释放,需要特定的appid才能使用,就可以这样:

 1 //1代表公共接口,0代表私密接口
2 var apilist = {
3 'chooseImage': 1,
4 'uploadImage': 1,
5 'previewImage': 0
6 };
7 //所有的应用id
8 var appids = [1, 2, 3, 4];
9 //白名单
10 var whitList = [{1: ['previewImage', '其他私密能力']}];

实话实说维护一个appid,这样做的成本比较高,单单做appid和秘钥对于调用者来说也挺麻烦,对于有些比较小的平台来说,可以采取域名白名单的方法,后端维护一个列表:

1 //域名白名单
2 var whitList = [
3 {'domain.com': ['previewImage', '其他私密能力']},
4 {'domain2.com': ['previewImage', 'uploadImage', '其他私密能力']}
5 ];

这种方法比较做起来成本较低,一些小一点的平台可以这样做,而这样做的话,需要考虑每个域名对应的App打开协议,可能会有打开需求,我们这里采用的比较简单的方案,域名白名单,表设计大概这样:

1 var whitList = [
2 {id: 'domain.com', apis: ['previewImage', '其他私密能力'], schema: 'xxxx://'},
3 {id: 'domain2.com', apis: ['previewImage', 'uploadImage', '其他私密能力'], schema: 'xxxx://'}
4 ];

我们明确知道某个域名具有哪些能力,如果不具有这些能力就不予理睬,我们也知道某个域名具有打开某个app的权限。

能力列表

明确了能力,以及能力限制,接下来我们便来整理一下几个核心的对外接口。

header的定义

我们这里做的第一件事情,依旧是header的定义,并且对于第三方,我们要求header只能是这个样子:

针对header我们有以下约定:

① 进入一个页面默认包含,返回+title+功能菜单三个按钮

② 返回按钮默认执行history.back()的操作,如果history.length为1,则退到native上一步操作

③ title默认读取html中的title标签,可使用接口更改

④ 关闭按钮默认不存在,在history比较深并且点击过一次返回按钮后展示出来,防止页面死循环假死

⑤ 功能菜单默认弹出以下菜单项,其中分享文案默认读取当前tdk(title+description)标签,和第一张图片,也可读取页面标签定制(也可以使用接口定制,事实上容器不会做这种业务工作,是业务框架层bridge做的工作),比如:

1 <meta name="med-title" content="分享标题">
2 <meta name="med-description" content="分享内容">
3 <meta name="med-link" content="http://....">
4 <meta name="med-img" content="http://....">

我们业务层代码,或者bridge代码会将之翻译为:

 1 wx.onMenuShareTimeline({
2 title: medTitle,
3 link: medLink,
4 imgUrl: medImg,
5 trigger: function (res) {
6 },
7 success: function (res) {
8 },
9 cancel: function (res) {
10 },
11 fail: function (res) {
12 }
13 });

分享到朋友圈&QQ空间

分享到朋友圈前端代码为:

 1 MED.origin = MED.origin || {};
2 //shareTimeline分享到朋友圈;shareAppMessage分享给朋友;shareQQ分享给qq好友;shareQZone分享到空间,设置方面稍作更改即可
3 MED.origin.medShareXXX = MED.medShareXXX = function (o) {
4 _.requestHybrid({
5 tagname: 'shareTimeline',
6 param: {
7 title: o.title,
8 desc: o.desc,
9 image: o.img,
10 url: o.link
11 },
12 callback: function(data) {
13 if(data.code === 0) {
14 o.success && o.success(data.data);
15 } else {
16 o.cancel && o.cancel(data.data);
17 }
18 }
19 });
20 };

H5上传图片方面的体验很差,这块我们在H5情况下依旧使用file上传,但是在容器里面释放几个图片操作接口

图片操作

 1 //选取图片,最初想把选取和上传合并的,后面想想还是分开合适
2 _.requestHybrid({
3 tagname: 'chooseImage',
4 param: {
5 //1-9张限制
6 count: 1,
7 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
8 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
9 },
10 callback: function(data) {
11 if(data.code === 0) {
12 //这块有一些疑问,选择和上传还是连着一起算了
13 o.success && o.success(data.data.localIds); // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片;
14 } else {
15 o.error && o.error(data.data);
16 }
17 }
18 });
19
20 //上传图片
21 _.requestHybrid({
22 tagname: 'uploadImage',
23 param: {
24 //由chooseImage获取
25 localId: 1,
26 isShowProgressTips: 1 // 默认为1,显示进度提示
27 },
28 callback: function(data) {
29 if(data.code === 0) {
30 o.success && o.success(data.data.url); // 返回src;
31 } else {
32 o.error && o.error(data.data);
33 }
34 }
35 });
36
37 //图片预览,预览的地方做个图片下载的功能
38 _.requestHybrid({
39 tagname: 'previewImage',
40 param: {
41 current: '', // 当前显示图片的http链接
42 urls: [] // 需要预览的图片http链接列表
43 }
44 });

获取网络状态

1 //获取网络状态
2 _.requestHybrid({
3 tagname: 'getNetworkType',
4 callback: function(data) {
5 //data.networkType 2g 3g 4g wifi
6 }
7 });

地图操作

Native的地理操作一块相对H5体验要好一些,特别是地图展示一块的体验要好得多,所以这两块也需要释放API:

 1 //获取经纬度信息
2 _.requestHybrid({
3 tagname: 'getLocation',
4 callback: function(data) {
5 if(data.code !== 0) return;
6 var res = data.res;
7 var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
8 var lOngitude= res.longitude; // 经度,浮点数,范围为180 ~ -180。
9 var speed = res.speed; // 速度,以米/每秒计
10 var accuracy = res.accuracy; // 位置精度
11 }
12 });
13
14 //根据经纬度等信息打开native地图
15 _.requestHybrid({
16 tagname: 'openLocation',
17 params: {
18 latitude: 0, // 纬度,浮点数,范围为90 ~ -90
19 longitude: 0, // 经度,浮点数,范围为180 ~ -180。
20 name: '', // 位置名
21 address: '', // 地址详情说明
22 scale: 1, // 地图缩放级别,整形值,范围从1~28。默认为最大
23 infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
24 }
25 });

所谓的name和地址是指下面信息框这一坨:

界面操作

关闭当前webview,回到native上一次操作:

1 _.requestHybrid({
2 tagname: 'closeWindow'
3 });

native键盘

H5在文字输入一块可以说是弱爆了,比Native体验差远了,所以我们在native键盘这块也做了一个nativeUI,如果需求允许可以使用:

 1 //唤起输入文字的软键盘
2 //这块代码有一些业务耦合,需要如何处理下????
3 _.requestHybrid({
4 tagname: 'showKeyboard',
5 param: {
6 hasImg: 1, //是否需要上传图片区域,如果需要则为1,不需要为0
7 count: 1, //如果需要图片上传,这里限制图片选择的数量,1-9
8 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
9 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
10 textMin: 20, //文字要求最少输入字符数
11 textMax: 500 //文字要求最多输入字符数
12 },
13 //输入结束的回调或者说点击发送时候的回调
14 callback: function (data) {
15 var cOntent= data.content;//文字内容
16 var urls = data.urls;//图片地址
17 }
18 });

结语

今天分析了一下第三方webview需要释放的接口,接下来我这边开始落地,我们真实工作中可能还要考虑新老容器过渡等问题,本文含金量相对较小,各位谨慎阅读吧。


推荐阅读
  • ![](https:s2.51cto.comimages202107121626044334772585.jpg)再往上基本就是架构师了,如果你想要做到架构师这个级别,那么这样的一 ... [详细]
  • 微信商户扫码支付 java开发 [从零开发]
    这个教程可以用作了解扫码支付的整体运行过程,已经实现了前端扫码,记录订单,回调等一套完整的微信扫码支付。相关链接:微信支 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • 本文是一篇翻译文章,介绍了async/await的用法和特点。async关键字被放置在函数前面,意味着该函数总是返回一个promise。文章还提到了可以显式返回一个promise的方法。该特性使得async/await更易于理解和使用。本文还提到了一些可能的错误,并希望读者能够指正。 ... [详细]
  • RN即ReactNative基于React框架针对移动端的跨平台框架,在学习RN前建议最好熟悉下html,css,js,当然如果比较急,那就直接上手吧,毕竟用学习前面基础的时间,R ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了Android平台各个版本的API级别、版本号以及平台亮点,从Android 1.0到Android 10.0,共涵盖了多个版本的特点和发展历程。详细内容请参考https://developer.android.google.cn/guide/topics/manifest/uses-sdk-element.html。 ... [详细]
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
author-avatar
此人已死689
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有