接上文:(阅读本文前,建议阅读前两篇文章先)
浅谈Hybrid技术的设计与实现
浅谈Hybrid技术的设计与实现第二弹
根据之前的介绍,大家对前端与Native的交互应该有一些简单的认识了,很多朋友就会觉得这个交互很简单嘛,其实并不难嘛,事实上单从Native与前端的交互来说就那点东西,真心没有太多可说的,但要真正做一个完整的Hybrid项目却不容易,要考虑的东西就比较多了,单从这个交互协议就有:
① URL Schema
② JavaScriptCore
两种,到底选择哪种方式,每种方式有什么优势,都是我们需要深度挖掘的,而除此之外,一个Hybrid项目还应该具有以下特性:
① 扩展性好——依靠好的约定
② 开发效率高——依赖公共业务
③ 交互体验好——需要解决各种兼容问题
我们在实际工作中如何落地一个Hybrid项目,如何推动一个项目的进行,这是本次我们要讨论的,也希望对各位有用。
文中是我个人的一些开发经验,希望对各位有用,也希望各位多多支持讨论,指出文中不足以及提出您的一些建议。
设计类博客
iOS博客
Android博客
https://home.cnblogs.com/u/vanezkw
代码地址:https://github.com/yexiaochai/Hybrid
因为IOS不能扫码下载了,大家自己下载下来用模拟器看吧,下面开始今天的内容。
总体概述在第一章,有兴趣大家去看
细节设计在第二章,有兴趣大家去看
本章主要为打补丁
边界问题在我们使用Hybrid技术前要注意一个边界问题,什么项目适合Hybrid什么项目不适合,这个要搞清楚,适合Hybrid的项目为:
① 有60%以上的业务为H5
② 对更新(开发效率)有一定要求的APP
不适合使用Hybrid技术的项目有以下特点:
① 只有20%不到的业务使用H5做
② 交互效果要求较高(动画多)
任何技术都有适用的场景,千万不要妄想推翻已有APP的业务用H5去替代,最后会证明那是自讨苦吃,当然如果仅仅想在APP里面嵌入新的实验性业务,这个是没问题的。
交互约定根据之前的学习,我们知道与Native交互有两种交互:
① URL Schema
② JavaScriptCore
而两种方式在使用上各有利弊,首先来说URL Schema是比较稳定而成熟的,如果使用上文中提到的“ajax”交互方式,会比较灵活;而从设计的角度来说JavaScriptCore似乎更加合理,但是我们在实际使用中却发现,注入的时机得不到保障。
iOS同事在实体JavaScriptCore注入时,我们的原意是在webview载入前就注入所有的Native能力,而实际情况是页面js已经执行完了才被注入,这里会导致Hybrid交互失效,如果你看到某个Hybrid平台,突然header显示不正确了,就可能是这个问题导致,所以JavaScriptCore就被我们弃用了。
JavaScriptCore可能导致的问题: ① 注入时机不唯一(也许是BUG) ② 刷新页面的时候,JavaScriptCore的注入在不同机型表现不一致,有些就根本不注入了,所以全部hybrid交互失效
如果非要使用JavaScriptCore,为了解决这一问题,我们做了一个兼容,用URL Schema的方式,在页面逻辑载入之初执行一个命令,将native的一些方式重新载入,比如:
1 _.requestHybrid({ 2 tagname: 'injection' 3 });
这个能解决一些问题,但是有些初始化就马上要用到的方法可能就无力了,比如:
① 想要获取native给予的地理信息
② 想要获取native给予的用户信息(直接以变量的方式获取)
作为生产来讲,我们还是求稳,所以最终选择了URL Schema。
明白了基本的边界问题,选取了底层的交互方式,就可以开始进行初步的Hybrid设计了,但是这离一个可用于生产,可离落地的Hybrid方案还比较远。
账号体系一般来说,一个公司的账号体系健壮灵活程度会很大程度反映出这个研发团队的整体实力:
① 统一的鉴权认证
② 短信服务图形验证码的处理
③ 子系统的权限设计、公共的用户信息导出
④ 第三方接入方案
⑤ 接入文档输出
⑥ ......
这个技术方案,有没有是一回事(说明没思维),有几套是一回事(说明比较乱,技术不统一),对外的一套做到了什么程度又是一回事,当然这个不是我们讨论的重点,而账号体系也是Hybrid设计中不可或缺的一环。
账号体系涉及了接口权限控制、资源访问控制,现在有一种方案是,前端代码不做接口鉴权,账号一块的工作全部放到native端。
native代理请求在H5想要做某一块老的App业务,这个APP80%以上的业务都是Native做的,这类APP在接口方面就没有考虑过H5的感受,会要求很多信息如:
① 设备号
② 地理信息
③ 网络情况
④ 系统版本
有很多H5拿不到或者不容易拿到的公共信息,因为H5做的往往是一些比较小的业务,像什么个人主页之类的不重要的业务,Server端可能不愿意提供额外的接口适配,而使用额外的接口还有可能打破他们统一的某些规则;加之native对接口有自己的一套公共处理逻辑,所以便出了Native代理H5发请求的方案,公共参数会由Native自动带上。
_.requestHybrid({ 3 tagname: 'apppost', 4 param: { 5 url: this.url, 6 param: params 7 }, 8 9 callback: function (data) { 10 scope.baseDataValidate(data, onComplete, onError); 11 } 12 });
这种方案有一些好处,接口统一,前端也不需要关注接口权限验证,但是这个会带给前端噩梦!
前端相对于native一个很大的优点,就是调试灵活,这种代理请求的方式,会限制请求只能在APP容器中生效,对前端调试造成了很大的痛苦
从真实的生产效果来说,也是很影响效率的,容易导致后续前端再也不愿意做那个APP的业务了,所以使用要慎重......
注入cookie前端比较通用的权限标志还是用cookie做的,所以Hybrid比较成熟的方案仍旧是注入cookie,这里的一个前提就是native&H5有一套统一的账号体系(统一的权限校验系统)。
因为H5使用的webview可以有独立的登录态,如果不加限制太过混乱难以维护,比如:
我们在qq浏览器中打开携程的网站,携程站内第三方登录可以唤起qq,然后登录成功;完了qq浏览器本来也有一个登录态,发现却没有登录,点击一键登录的时候再次唤起了qq登录。