UIWebView
笔记内只涉及单独使用 UIWebView
与 JavaScript 交互的内容。 UIWebView
还可以和 JavaScriptCore
配合使用, 对应内容会在之后以 JavaScriptCore
为主题的笔记中。
基本的页面加载、交互
以打开、关闭作为例子。但还包括了前进 goBack
、回退 goForward
、重新加载 reload
、停止加载 stopLoading
等方法,或者:是否正在加载 isLoading
、是否可以回退 canGoBack
、是否可以前进 canGoForward
这样的属性。可以自行查询文档进行了解。
加载在线网页
加载本地页面
原生调用 JavaScript
直接使用 stringByEvaluatingJavaScript(from:)
使用 stringByEvaluatingJavaScript(from:)
方法,就可以在原生中通过如下方法来调用。
这里通过 webViewDidStartLoad
委托(delegate
,下同),在页面开始加载的时候触发对应的 JavaScript。
假设加载的页面引入的 JavaScript 包含如下三个函数,在原生里就可以通过对应的方法进行调用、获取返回值。
注入 JavaScript
不确定是不是约定促成这里该用「注入」这个词,具体的调用方法不变仍使用 stringByEvaluatingJavaScript(from:)
,主要的区别在于:加载一个远程别人的网站网页,可以从我们当前系统本地(Bundle.main
)对对方网页注入一段 JavaScript,使得原生中对加载的网页做一些优化修改。
演示中的操作:
- 加载一个本地文件夹中的
index.html
; index.html
本身引入了index.css
和index.js
;- 当这个三个文件加载完毕,再使用
UIWebView
的方法来加载一个file.js
文件。
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 胡椒)