Hybrid容器设计之第三方网站

平台化容器API释放

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

浅谈Hybrid技术的设计与实现

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

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

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

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

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

② 分享接口

③ 微信支付

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

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

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

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

这个当history过深(不为1时)后也会产生一个关闭按钮,直接回到上一个native页面。

我们这里约定,对于第三方网站,这些Native UI我们都不可定制化(但是能通过释放接口配置增添菜单项目),甚至风格色彩都是不可定制的,如果哪天我们的APP风格变了,那么第三方网站只能适配我们的APP(虽然APP便整体风格这种事情有点操蛋,但是在中小公司还是比较常见)

这里可定制的是:

① 标题展示

② 分享出去的文字、图片等(这块参考微信)

③ 不同的APP这块可能会有定制化需求,这块也最好标准化,不让产品有过多的瞎想

除了登录之外,另一个比较常用的服务就是唤起支付(APP中的支付),然后APP公共页面再引导用户选择微信或者支付宝支付。

其实唤起支付属于H5跳Native(或者Hybrid)的一类,与之类似的有:

① 打开某一个native页面,比较典型的是在网页贴吧中打开一个网址如果安装了贴吧APP,会直接打开那个页面

② 这里也有可能是打开第三方APP,而打开第三方APP这种功能,对于比较大的APP平台会做严格的限制

因为图片上传什么对H5来说是一个比较麻烦的功能,完全依赖H5可能体验不好,于是native方可能会释放一些图片操作的接口如:

① H5调用native的选取相册&图片接口

② 图片预览接口(查看大图)

③ 上传图片

④ 下载图片

有些比较特别的网站也许还会有获取当前网络状态的接口或者地理位置接口或者调用扫一扫功能(场景较少),而对于UI层面的操作又会包含关闭当前窗口(同点击关闭按钮)的接口。

所有的这些功能,我们最初就应该设想清楚,并且清晰的知道每一个接口适用于什么场景,在能力列表出来后,我们就要做另一个事情了:权限限制。

权限限制

微信使用了一个appid,去限制每一个接入方的能力,甚至可以以收费的形式释放某些接口,可以预见,如果微信开放打开第三方App的收费功能,会有很多公司争相埋单。这种appid的行为,相当于一种统一收口的动作,虽然接入方千奇百怪,但是所有的接入方如果要使用容器的能力,甚至想在容器中展示,就必须有一个appid。

另一方面,appid的使用其实成本比较高,前端需要额外的接口访问不说,平台方还需要提供一个第三方网站让第三方网站管理自己的应用,这个对于一些小平台甚至伪平台有一些得不偿失,我们来简单看看一个demo:

 1 //第三方网站要用什么接口,必须先声明
 2 wx.config({
 3     debug: false, 4     appId: 'wxf8b4f85f3a794e77',//服务器端读出
 5     timestamp: 1485169627,//服务器端读出
 6     nonceStr: 'jhGQ4jiN4CQpaGPC',//服务器端读出
 7     signature: 'a19573b7f65427a33a96f2a57a4f40075135a5b4',//服务器端读出
 8     jsApiList: [
 9         'onMenuShareTimeline',10         'onMenuShareAppMessage',11         'onMenuShareQQ',12         'onMenuShareWeibo',13         'onMenuShareQZone'
14     ]
15 });
 1 // 2. 分享接口
 2 // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口
 3 document.querySelector('#onMenuShareAppMessage').onclick = function () {
 4     wx.onMenuShareAppMessage({
 5         title: '分享标题', 6         desc: '分享描述', 7         link: 'http://movie.douban.com/subject/25785114/', 8         imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg', 9         trigger: function (res) {
10             // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
11             alert('用户点击发送给朋友');
12         },13         success: function (res) {
14             alert('已分享');
15         },16         cancel: function (res) {
17             alert('已取消');
18         },19         fail: function (res) {
20             alert(JSON.stringify(res));
21         }
22     });
23     alert('已注册获取“发送给朋友”状态事件');
24 };

如果没有第一段代码的声明,第二段代码就没用;如果appid没有相关接口权限,这里就注册不了,也不能调用接口,比如我们就可以为某一个appid赋予打开第三方app的权限,或者我们定义某个appid具有app,其他应用可以根据打开对应app,没有的话就引导下载:

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',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',// 可以指定是原图还是压缩图,默认二者都有
 8         sourceType: ['album',// 可以指定来源是相册还是相机,默认二者都有
 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',// 可以指定是原图还是压缩图,默认二者都有
 9         sourceType: ['album',// 可以指定来源是相册还是相机,默认二者都有
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需要释放的接口,接下来我这边开始落地,我们真实工作中可能还要考虑新老容器过渡等问题,本文含金量相对较小,各位谨慎阅读吧。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1.小程序的优缺点优点:不需下载、卸载使用方便缺点:嵌套在微信中,属于微信的子应用2.使用的技术实际上是Hybrid技术的应用HybridApp(混合模式移动应用),使用网页语言和程序语言共同开发小程序兼具了NativeApp所有优势,也兼具了WebApp使用Html5跨平台开发低成本注:微信小程序与传
端口类型-HybridHybrid端口是交换机上既可以连接用户主机,又可以连接其他交换机的端口。Hybrid端口既可以连接接入链路又可以连接干道链路。Hybrid端口允许多个VLAN的帧通过,并可以在出端口方向将某些VLAN帧的Tag剥掉。华为设备默认的端口类型是Hybrid。 Hybrid端口收发数据帧的规则
不同vlan同段IP通信LSW1vlan1vlan2vlan3interfaceEthernet0/0/1porthybriduntaggedvlan2to3interfaceEthernet0/0/2porthybridpvidvlan2porthybriduntaggedvlan2to3interfaceEthernet0/0/3porthybridpvidvlan3porthybriduntaggedvlan2to3
VLAN中access、Trunk和Hybrid三种端口区别:acesss:1、发送不带标签的报文2、一般与PC\server相连时使用3、只可以属于一个VLANTrunk:1、发送带标签的报文2、一般用于交换机级联端口传递多组VLAN信息使用3、可以属于多个VLANHybrid:1、混合端口可以同时属于多个vlan2、混合端口
这系列文章内容包括:STP、RSTP、MSTP、VLAN、LACP、SuperVLAN。以学习实验配置为主要目标;实验引用华为官方na在线视频中实验。6.3VLAN原理和配置实验截图:配置第一个交换机:修改端口类型acc、配置端口所属vlan、配置trunk端口。实验心得:有一个问题,当你配置e0/0/3为trunk以及al
实验一:交换机端口类型配置1.拓扑图如下图所示:2.实验要求:实现二层网络中工程部和市场部不能互访,但是都能与网络中心的服务器通信3.请写出你的配置思路、配置命令实验思路:将交换机SW1、SW2、SW3之间配置为trunk链路,其他接口配置为Hybrid链路;实验配置名如下:SW1sysnameSW
   这个英文材料对我一个英语一般的学生表示亚历山大啊,不过还是勉强看完了,说说自己的看法吧。   谷歌作为一家商业公司,利润是其基本的追求目标,这一点是毋庸置疑的。但是谷歌并没有被这个基本目标挡住了视野,无数公司失败的经验告诉我们,如果缺少创新,公司的一切发展
简介:VLAN10内通信,VLAN20内通信,VLAN30与VLAN10、VLAN20、VLAN30皆可通信Hybrid接口应用拓扑图:  一、配置PC机ip并测试相互能否ping通 PC名称IP子网掩码网关PC110.1.1.1255.255.255.010.1.1.254PC210.1.1.2255.255.255.010.1.1.254PC310.1.1.3
通常情况下,公司对内网的使用远远高于对外网的使用。公司的内部网络是由二层交换网络构建的,所以二层网络设计的好坏直接影响公司的正常业务。好的设计不仅使功能得到体现,还可以应对一些未知的隐患,如线路损坏、设备损坏等。下面我们主要对华为的二层设备进行了解,不过首先要了解的就
手机app代表了互联网时代的发展,促使我们的日常生活也变得越来越轻松,不管是哪个行业或者企业,在人们手机上存在最多的还是APP,手机APP逐渐的超越了网络,本身这些APP系统就是一个大型的APP系统,具体APP怎么开发呢?开发出来的手机APP,主要还是通过编程的方式设计出来的,有了变成那么就需要程
我想导出一种简单可靠的方法来自动提升正在运行的批处理,而无需使用其他线程中建议的额外的VBS文件或提升的快捷方式.通过javascript从批处理调用UAC对话框可确保简短的简单代码.在对话框中选择“是”,但错误对话框弹出时(在Cmd窗口外部)“Windows找不到’test.bat’”,下面的脚
无论如何,我可以在FORTRAN程序中使用BoostGraphLibrary(BGL)来使用图形数据结构.任何人都可以帮助我或给我一个提示.我想在我的MPI-FORTRAN代码中的几个处理器上进行并行图结构.是否可以使用BoostGraphLibrary(BGL)来达到此目的!亲切的问候,谢夫解决方法:你必须构造一个用C语
原文链接:http://www.cnblogs.com/iamzyf/p/3515889.html其实问题很简单:我的产品页面在 http://www.gdtsearch.com/products.spiderstudio.docapi.htm,这是一个静态页面;而我所有的技术博客都在博客园中.为了让访问者能够直接在产品页面中看到我最
Hybrid接口是华为特有的一种接口Hybrid接口是既可以连接普通终端的接入链路,又可以连接交换机间的干道链路。简单说就是Hybrid接口既能实现Access的功能又能实现Trunk接口的功能。实验模拟:实验拓扑:实验编址:测试连通性:查看交换机接口类型(默认情况下都是hybrid类型)displayportvlan
原生APP开发-NativeApp:需要用户下载安装使用,可访问手机的所有功能(GPS,摄像头,重力加速器),拓展性强,是专门为某种操作系统开发的(IOS,Android,黑莓等),但是开发和维护的成本都比较高 webApp:html5语言写出的app,不需要下载安装,基本上就是触屏版的网页,可以在多个设备上运行,有很大的局限性
拓扑图如下:(1)sw1的配置:<Huawei><Huawei>system-view//切换到系统视图Entersystemview,returnuserviewwithCtrl+Z.[Huawei]sysnamesw1//配置主机名Oct25201916:29:31-08:00sw1DS/4/DATASYNC_CFGCHANGE:OID1.3.6.1.4.1.2011.5.25.191
程序员常用等宽字体1SourceCodePro2CourierNew(传统)3Consolas4Monaco5中文雅黑混合版(YaHeiConsolasHybrid)
Japan'shybridmodelinventoryofhairEwhaRinkaLead:passed37thbirthdayofthepear,theeyesofeveryonestillhasaLolita-likegirltemperament,herinterpretationoftheinvolutionBOBlongghdhairstraightener hair,andevensetoffinas
1url不要用hash模式,如果涉及到外部如firebase方式直接发送给客户端动态链接,要求打开app内h5地址的时候,这个#会被截断,客户端无法解析2尽量在多页面,当客户端由不同入口进入的时候,前端尽可能做多业务拆分,避免以后所有模块在一起,一次修改要全部上线,3移动端输入框键盘要求输