前言
了解本文之前需要准备JS和WebView的一些基础知识,需要知道JS的基本语法和WebView调用JS的常用接口。
iOS实现JS和Native交互的WebView有UIWebView和WKWebView。通过KVC拿到UIWebView的JSContext,通过JSContext实现交互。
WKWebView有了新特性MessageHandler来实现JS调用原生方法。从实现思路是来讲,UIWebView和WKWebView是一样的。
所以,本文只介绍WKWebView上JS和Native的交互思路,UIWebView有需求的可以模仿实现。
JS和Native交互常用的场景
常用的分为下面几种场景:
H5获取Native用户信息(这种比较简单,只需要Native注入JS就行了,思路有三种下面介绍)
H5传递信息给Native,调用Native分享(这种属于JS调用Native)
Native告诉H5分享结果(这种属于Native调用JS)
下面一一介绍,实现如下:
H5获取Native用户信息
现有用户信息格式如下,需要注入到JS,供H5调用:
|
|
注入JS变量
Native注入JS变量实现如下
|
|
通过遍历userInfo的keys,把key作为变量,value作为String值,注入到JS上下文中。
在H5中实现调用如下
|
|
注入JS对象
Native注入JS对象实现如下
|
|
通过把userInfo字典转化成json,作为对象赋值给userInfo,注入JS上下文中。
在H5中实现调用如下
|
|
注入JS函数
Native注入JS函数实现如下
|
|
通过封装getUserInfo匿名函数,执行函数return我们的对象,生成全局对象iOSApp,调用iOSApp.getUserInfo()
。
这样写的好处是,我们的H5在调用函数的时候,可以很容易知道哪些是原生注入,防止和本地造成冲突,便于理解。
在H5中实现调用如下
|
|
以上讲了三种方式实现用户信息的传递,都是通过WKUserContentController注入JS实现的,实际上我也可以通过WebView的evaluateJavaScript方法实现注入。
evaluateJavaScript实现注入
同样的WebView的调用H5,提供了evaluateJavaScript接口,此接口既可以执行JS函数回调结果,也可以注入JS。
下面使用接口实现JS函数的注入
|
|
在WebView加载完成之后,使用evaluateJavaScript实现了JS函数的注入,H5实现调用正常。
H5传递信息给Native,调用Native分享
很多时候H5需要传递信息给我们的Native,我们Native再执行相应的逻辑。
Native实现代码如下
|
|
userContent.add(self, name: "shareAction")
本地添加shareAction的接口声明,当JS调用shareAction回调代理方法,实现参数捕获(WKScriptMessage)。
这样我们本地就得到了分享的传参了,然后可以调用本地SDK实现分享的逻辑了。
H5实现代码如下
|
|
Native告诉H5分享结果
上面实现了JS传参数给Native,但是Native怎么告诉H5分享结果呢,下面是实现逻辑。
Native实现如下
|
|
获取shareSucc的函数回调名称,在合适的时候我们可以通过这个JS函数回调,告诉H5我们的分享结果。
JS实现如下
|
|
之前postMessage是发送的字典,由于我们的需求增多了,所以还是改成数组。
最后发送shareSucc的字符串,告诉Native我们有一个shareSucc的函数可以接收分享的结果。
JS和Native统一封装
上面讲了JS回调Native,Native回调JS,实现了我们常用的一些业务逻辑。
里面有很多重复的代码,实现起来也不友好,下面我们把这些重用的全部封装一下,改成好用的接口给上层,使Native和JS的开发人员都不用操心太多的实现细节。
H5界面的代码
|
|
构造基础类JWebViewController
|
|
继承JWebViewController,实现业务
|
|
讲解JWebViewController
构造JKWkWebViewHandler类,存储信息
|
|
添加JS,使用JKWkWebViewHandler存储
|
|
创建JS脚本,使用iOSApp对象封装,异步回调传回Native的函数window.webkit.messageHandlers.xxx直接封装在JS函数中。
这样有一个好处,H5调用JS,直接iOSApp.xxx(xxx)就行了,不需要写window.webkit.messageHandlers.xxx这些代码。
这对于H5来说,跟平时写的JS脚本没有什么区别,方便了调用。
对于Native来说,帮H5做了JS的回调的封装,并通过handler回调得到自己想要的参数,通过这个封装,两端的工作都只需要关注
业务层就行了,继承JWebViewController,可以专心写业务逻辑。
|
|
构造JS,实现传参给H5页面
|
|
注入JS脚本到WKWebViewConfiguration中
|
|
合适的时候释放JS的handler,注意不释放的话,Controller不会调用deinit,发生内存泄露。
|
|
代码示例放到Github了,有需要的可以下载查看。
关注我
欢迎关注公众号:jackyshan,技术干货首发微信,第一时间推送。