UIWebView
笔记内只涉及单独使用 UIWebView 与 JavaScript 交互的内容。 UIWebView 还可以和 JavaScriptCore 配合使用, 对应内容会在之后以 JavaScriptCore 为主题的笔记中。
基本的页面加载、交互
以打开、关闭作为例子。但还包括了前进 goBack、回退 goForward 、重新加载 reload、停止加载 stopLoading 等方法,或者:是否正在加载 isLoading、是否可以回退 canGoBack、是否可以前进 canGoForward 这样的属性。可以自行查询文档进行了解。
加载在线网页
加载本地页面
html 文件。原生调用 JavaScript
直接使用 stringByEvaluatingJavaScript(from:)
使用 stringByEvaluatingJavaScript(from:) 方法,就可以在原生中通过如下方法来调用。
这里通过 webViewDidStartLoad 委托(delegate,下同),在页面开始加载的时候触发对应的 JavaScript。
假设加载的页面引入的 JavaScript 包含如下三个函数,在原生里就可以通过对应的方法进行调用、获取返回值。
注入 JavaScript
console 中会打印 returned value from JavaScript: hello Lien。不确定是不是约定促成这里该用「注入」这个词,具体的调用方法不变仍使用 stringByEvaluatingJavaScript(from:),主要的区别在于:加载一个远程别人的网站网页,可以从我们当前系统本地(Bundle.main)对对方网页注入一段 JavaScript,使得原生中对加载的网页做一些优化修改。
演示中的操作:
- 加载一个本地文件夹中的 index.html;
- index.html本身引入了- index.css和- index.js;
- 当这个三个文件加载完毕,再使用 UIWebView的方法来加载一个file.js文件。
JavaScript 调用原生
UIWebView 拦截请求,实现 JavaScript 从内部调用外部的原生。如果把原生调用 JavaScript 看作是由外至内的调用,那么相反、由内至外的使用 UIWebView 来使 JavaScript 调用的官方方法是没有的。而 JavaScript 调用原生方法之所以成立,实际上是通过外部拦截拦截内部的请求1。
比如说在加载完毕的 html 中有以下这样一个链接
要在原生中拦截到这个 hello://lien 的具体的代码就如下
这里在函数中的操作是:
- 拦截名为 hello协议;
- 获取协议后的 path,也就是lien;
- 将 path的string作为window.alert()方法的参数,通过webview.stringByEvaluatingJavaScript()方法执行该 JavaScript 函数;
- 因为拦截到了对应的hello协议,在委托方法里最后返回false,阻止UIWebView继续执行该请求(跳转了也是个404)。
JavaScript 调用原生的单独演示
首先是 html 中一个的按钮。
JavaScript 来给按钮进行对时间进行监听。
接着我们需要一个对于创建 <iframe> 的分装方法。
然后是具体的回调函数。
最后,是 iOS 中对应的方法2。
- 对这一块内容更加详细的说明可以参考腾讯 Bugly 的这篇:解耦—Hybrid H5跨平台性思考 ↩︎ 
- 将 - url.query解析成- Dictionary<String:String>可以参考这里,获取- url.query中一个- param对应的- value可以参考这里,还有对- url进行 encode 和 decode 可以参考这里 两个相关 API: addingPercentEncoding(withAllowedCharacters:) 、 removingPercentEncoding。 ↩︎
技术发展迭代很快,所以这些笔记内容也有类似新闻的时效性,不免有过时、或者错误的地方,欢迎指正 ^_^。
BEST
Lien(A.K.A 胡椒)
