在介绍hybird开发技术之前,我们先了解下在移动领域经常会听到native app、web app、hybird app等术语,并简单说下他们之间的区别。这三者各有优劣,hybird技术算是native原生开发和web开发的合成物。
Native app从应用商店下载安装在移动设备上,可点击设备屏幕上的对应icon进行访问。能利用平台支持的各种特性:摄像头、GPS、各类传感器、通讯录等等;可以聚合平台提供的各类手势操作;利用系统提供的通知系统并能在离线的情况下良好工作。Native app直接运行在平台之上,性能更好,动画的流畅度,界面的相应速度一般来说都比Web app要好。缺点是Native app的每次更新都需要提交审核,开发人力大。不能热更新。
Web app不是真正的应用,本质上只是各类站点,但是尽量提供Native app的视觉和感官体验。它们运行在浏览器之上,通过经典的web前端开发方式开发。目前,浏览器提供的功能越来越丰富:比如GPS、离线应用、sevice worker等特性的支持;并且浏览器引擎性能的持续优化,也使得站点运行的速度变快,对动画的支持更加流畅。但是在复杂手势支持、横竖屏检测、后台运行、通知等还是不如Native app。Web app的一个明显的优势是推广,便于用户发现。一般来说,当人们碰见问题,习惯性的是去各类搜索引擎上搜索答案,如果站点内容和用户搜索关键字匹配度高,很可能会被用户发现点击带来流量。而对于应用来说,需要用户去商店,搜索应用,下载,然后在应用内探索自己想要的答案,步骤太过繁琐,所以应用的推广相对来说难度更加高一些。
近几年比较火爆的还有Progressive Web Apps(PWAs),旨在让web app通过提供push 通知、离线支持、安装到主屏幕、响应式开发设计等方式渐进式的增强和展示内容,给用户一个更加类似native app的体验。目前各浏览器对这些特性的支持程度不一。
Hybird app是部分原生开发,部分web开发。类似原生app,通过应用商店下载安装,能利用大量的平台特性和设备特性;类似Web app,界面主要通过(html+js+css)开发,运行在浏览器之上,只不过该浏览器内嵌在应用之内。Hybird app之所以流行是因为它允许跨平台开发,同样的前端代码(html+js+css)可下发运行在不同操作系统之上的app,以此节省大量的开发人力。总体来说,Hybird app的目的是希望结合Native app和Web app的优势。
今天我们着重了解下当前糯米自研的hybird框架。
总得来说,糯米hybird框架在内置的浏览器中注入了一个js库【以下统称hybird.js】,通过该库提供的接口可以调用部分原生平台的能力。
1、诸如功能相关的有获取地理位置、分享信息到微博微信、打开摄像头、通讯录、用户的账号信息等
2、界面相关的有定制navigationbar的样式、标题、右上角按钮等
3、设备信息相关的有当前设备类型、操作系统版本等等。
总体架构如下图。
考虑到移动应用的网速和性能问题,业务被拆分成一个个独立的模块。由FE同学将相关的资源(js、html、css、image)打包成zip包,发布到cdn。app会在适当的时机(启动、前后天切换、用户主动请求打开某个业务界面等)拉取这些zip包,并做增量式更新。增加的这一层缓存极大的提高了用户访问界面的速度,同时也引发了新的问题:
1、内置浏览器现在通过本地html文件展示页面,加载的协议变成file://,由于浏览器的安全限制,怎么处理跨域请求,localstorage等问题?
解决方案:跨域请求限制可以通过在hybird.js中提供网络请求接口,转为app网络请求的方式解决;localstorage限制可以通过在hybird.js提供功能接口转为访问本地app模拟的浏览器提供的localstorage来实现。
2、怎么处理加载的html文件的安全性问题,比方说加载该html的父目录中的资源?
解决方案:由于目前接入的业务基本都是本厂自开发,且所有的网络流量走https,该问题暂未处理。后续应该会在网络协议上加拦截对网络请求进行过滤处理。
3、第三个问题和上述说的增加的这一层缓存无关:由于内置浏览器内注入了功能js库,通过该js接口能获取到私密数据信息。怎么保障该内置浏览器在加载https://evil.com的时候私密信息不泄露。
解决方案:提供配置平台,每个在线url需要在注入hybird.js的内置浏览器打开的话,需要在配置平台进行注册。app在特定时机会去拉取该配置,每次调用功能接口的时候,native 代码会根据配置文件校验当前加载的url的权限,权限不通过则不返回用户账号等私密信息。
上面主要讲述了会遇到的几个主要问题。hybird开发的另一个重要环节就是js和oc的相互调用的处理。目前在糯米hybird框架中我们所采用的方式是:
1、js调用oc
a> js创建一个不可见iframe,执行iframe.src = 'hybirdapi://_?' + 'method=' + method + '&args=' + encodeURIComponent(args); 其中 method为需要调用的native方法名,args为需要传递的参数
b> 在oc代码中实现webview的delegate方法- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 获取到ifame的加载url,对此url进行解析,得到method和args值,通过oc的runtime反射机制,反射到对应oc方法,进行方法调用,从而实现js需要的功能。
2、oc调用js: 通过执行UIWebView的- (NSString *) stringByEvaluatingJavaScriptFromString : (NSString *)script方法
综述:在本篇文章中我们主要对比了native app、web app、hybird app的差异和优劣,由此了解到通过hybird开发app的原因。其余的章节主要介绍了糯米hybird框架的设计,碰见的三个关键问题,以及js和oc通信桥梁。