iOS 混合应用的关键点分析 - 仿 Android 平台 WebView 可注入本地对象方法的功能实现要点
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商业用途-保持一致”创作公用协议
对于 iOS 和 Android 平台来说,各自的流畅览器组件 UIWebView 和 WebView 都可以很容易地在本地代码中调用 WebView 内页面 JS 脚本。
然后,从 JS 调用本地方法,只有 Android 平台的 WebView 组件提供了,这也很容易理解,毕竟 Android WebView 组件以 Java 实现,想向其反射注入些功能也时很容易的,但具体实现尚未去分析源码证实。
对于 iOS 来说,只有一个切入点,那就是通过 UIWebViewDelegate 的页面加载事件,获得到页面内的加载事件。
那么如何在页面内很容易地触发一个页面加载事件,以便能在本地代理方法中截获并响应这一 HTML 页面内事件呢?
这一问题,即已抽象出了函数调用方的事件触发,和函数被调方的事件响应机制的映射双方。
1、通过 a 标签,早些年的 PhoneGap 框架即为这样实现的,不过感觉有些拘束;
2、加入 input 组件,并设置为隐藏状态,通过设置其 onClick 事件,动态更新其加载的链接,这个对原页面有要求,且附属操作过多;
3、像 img 的页面二次加载其 src 指定图片的原理,即不会影响原页面产生刷新,又会触发页面加载;
实际测试发现,该组件只在页面初次加载时,进行串行加载,即使加了 defer 或 async 参数,也无法动态触发。
后发现一个开源库,其采用了 iframe 的 src 来触发加载,动态将 iframe 添加到页面,就会触发加载 src 链接的事件,能被本地捕获,然后马上再移除这个 iframe。
这个开源库能很好地将 iOS 本地对象的所有方法动态加载给当前页面的 window 对象,可以在页面内直接调用对应对象的方法。
不过该库实现者对 iOS 方法签名的理解有误,所以,对于多参数方法,并没有能很好地解决。