WKWebView新特性及JS交互

本博文原始地址在: 
http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=400327803&idx=1&sn=2a09fa94dd605a9f03bbc16f998e5717#rd

本博客不会在此处更新文章,请关注微信公众号,更新的内容只会是在原文更新。

引言

一直听说WKWebViewUIWebView强大许多,可是一直没有使用到,今天花了点时间看写了个例子,对其API的使用有所了解,为了日后能少走弯路,也为了让大家更容易学习上手,这里写下这篇文章来记录如何使用以及需要注意的地方。

温馨提示:本人在学习使用过程中,确实有此体会,WKWebView的确比UIWebView强大很多,与JS交互的能力显示增强,在加载速度上有所提升。

WKWebView新特性

  • 性能、稳定性、功能大幅度提升
  • 允许JavaScript的Nitro库加载并使用(UIWebView中限制)
  • 支持了更多的HTML5特性
  • 高达60fps的滚动刷新率以及内置手势
  • GPU硬件加速
  • KVO
  • 重构UIWebView成14类与3个协议,查看官方文档

准备工作

首先,我们在使用的地方引入模块:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> Webkit</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

在学习之前,建议大家先点击WKWebView进去阅读里面的相关API,读完一遍,有个大概的印象,学习起来就很快了。

其初始化方法有:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>()
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(frame: CGRect)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(frame: CGRect, configuration: WKWebViewConfiguration)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

加载HTML的方式与UIWebView的方式大致相同。其中,loadFileURL方法通常用于加载服务器的HTML页面或者JS,而loadHTMLString方法通常用于加载本地HTML或者JS:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadRequest(request: NSURLRequest) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 9.0以后才支持   </span>
@available(iOS <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9.0</span>, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadFileURL(URL: NSURL, allowingReadAccessToURL readAccessURL: NSURL) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 通常用于加载本地HTML或者JS</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadHTMLString(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span>: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, baseURL: NSURL<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 9.0以后才支持</span>
@available(iOS <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9.0</span>, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadData(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>: NSData, MIMEType: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, characterEncodingName: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, baseURL: NSURL) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

与之交互用到的三大代理:

  • WKNavigationDelegate,与页面导航加载相关
  • WKUIDelegate,与JS交互时的ui展示相关,比较JS的alert、confirm、prompt
  • WKScriptMessageHandler,与js交互相关,通常是ios端注入名称,js端通过window.webkit.messageHandlers.{NAME}.postMessage()来发消息到ios端

创建WKWebView

首先,我们在ViewController中先遵守协议:

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ViewController</span>: <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UIViewController</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WKScriptMessageHandler</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WKNavigationDelegate</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WKUIDelegate</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

我们可以先创建一个WKWebView的配置项WKWebViewConfiguration,这可以设置偏好设置,与网页交互的配置,注入对象,注入js等:

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建一个webiview的配置项</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> configuretion = WKWebViewConfiguration()

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Webview的偏好设置</span>
configuretion.preferences = WKPreferences()
configuretion.preferences.minimumFontSize = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>
configuretion.preferences.javaScriptEnabled = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 默认是不能通过JS自动打开窗口的,必须通过用户交互才能打开</span>
configuretion.preferences.javaScriptCanOpenWindowsAutomatically = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 通过js与webview内容交互配置</span>
configuretion.userContentController = WKUserContentController()

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个JS到HTML中,这样就可以直接在JS中调用我们添加的JS方法</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> script = WKUserScript(source: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"function showAlert() { alert('在载入webview时通过Swift注入的JS方法'); }"</span>,
  injectionTime: .AtDocumentStart,<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在载入时就添加JS</span>
  forMainFrameOnly: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 只添加到mainFrame中</span>
configuretion.userContentController.addUserScript(script)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 添加一个名称,就可以在JS通过这个名称发送消息:</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// window.webkit.messageHandlers.AppModel.postMessage({body: 'xxx'})</span>
configuretion.userContentController.addScriptMessageHandler(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, name: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AppModel"</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>

创建对象并遵守代理:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span> = WKWebView(frame: self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bounds</span>, configuration: configuretion)

self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.navigationDelegate</span> = self
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.UIDelegate</span> = self</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

加载我们的本地HTML页面:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">let url = NSBundle<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mainBundle</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.URLForResource</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"test"</span>, withExtension: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"html"</span>)
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.loadRequest</span>(NSURLRequest(URL: url!))
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addSubview</span>(self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

我们再添加前进、后退按钮和添加一个加载进度的控制显示在Webview上:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span> = UIProgressView(progressViewStyle: <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Default</span>)
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.frame</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.size</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.width</span> = self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.frame</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.size</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.width</span>
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.backgroundColor</span> = UIColor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.redColor</span>()
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addSubview</span>(self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span>)

self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.navigationItem</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.leftBarButtonItem</span> = UIBarButtonItem(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"上一个页面"</span>, style: <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Done</span>, target: self, action: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"previousPage"</span>)
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.navigationItem</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.rightBarButtonItem</span> = UIBarButtonItem(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"下一个页面"</span>, style: <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Done</span>, target: self, action: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"nextPage"</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

页面前进、后退

对于前进后退的事件处理就很简单的,要注意判断一下是否可以后退、前进才调用:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func previousPage() {
    if self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.canGoBack</span> {
      self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.goBack</span>()
    }
}

func nextPage() {
    if self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.canGoForward</span> {
      self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.goForward</span>()
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

当然除了这些方法之处,还有重新载入等。

WKWebView的KVO

对于WKWebView,有三个属性支持KVO,因此我们可以监听其值的变化,分别是:loading,title,estimatedProgress,对应功能表示为:是否正在加载中,页面的标题,页面内容加载的进度(值为0.0~1.0)

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 监听支持KVO的属性</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.webView.addObserver(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, forKeyPath: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loading"</span>, options: .<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">New</span>, context: nil)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.webView.addObserver(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, forKeyPath: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"title"</span>, options: .<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">New</span>, context: nil)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.webView.addObserver(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, forKeyPath: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"estimatedProgress"</span>, options: .<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">New</span>, context: nil)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

然后就可以重写监听的方法来处理。这里只是取页面的标题,更新加载的进度条,在加载完成时,手动调用执行一个JS方法:

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">MARK</span>: - KVO
override func observeValueForKeyPath(<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">keyPath</span>: String?, ofObject <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">object</span>: AnyObject?, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">change</span>: [String : AnyObject]?, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">context</span>: UnsafeMutablePointer<Void>) {
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> keyPath == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loading"</span> {
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loading"</span>)
  } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> keyPath == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"title"</span> {
    self.title = self.webView.title
  } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> keyPath == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"estimatedProgress"</span> {
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(webView.estimatedProgress)
    self.progressView.setProgress(Float(webView.estimatedProgress), <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">animated</span>: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>)
  }

  <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 已经完成加载时,我们就可以做我们的事了
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> !webView.loading {
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 手动调用JS代码
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> js = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"callJsAlert()"</span>;
    self.webView.evaluateJavaScript<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(js)</span> { <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(_, _)</span> -></span> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
      <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"call js alert"</span>)
    }

    UIView.animateWithDuration<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.55</span>, animations: { () -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
      self.progressView.alpha = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>;
    })</span>
  }
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

WKUIDelegate

我们看看WKUIDelegate的几个代理方法,虽然不是必须实现的,但是如果我们的页面中有调用了js的alert、confirm、prompt方法,我们应该实现下面这几个代理方法,然后在原来这里调用native的弹出窗,因为使用WKWebView后,HTML中的alert、confirm、prompt方法调用是不会再弹出窗口了,只是转化成ios的native回调代理方法:

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">MARK</span>: - WKUIDelegate
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 这个方法是在HTML中调用了JS的alert()方法时,就会回调此API。
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 注意,使用了`<span class="javascript" style="box-sizing: border-box;">WKWebView</span>`后,在JS端调用alert()就不会在HTML
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 中显示弹出窗口。因此,我们需要在此处手动弹出ios系统的alert。
func webView<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">alert</span> = <span class="hljs-title" style="box-sizing: border-box;">UIAlertController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tip"</span>, message: message, preferredStyle: .Alert)</span>
  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addAction</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ok"</span>, style: .Default, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> We must call back js
    completionHandler()
  }))</span>

  <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">presentViewController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(alert, animated: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>, completion: nil)</span>
}

<span class="hljs-title" style="box-sizing: border-box;">func</span> <span class="hljs-title" style="box-sizing: border-box;">webView</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: (Bool) -> Void)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">alert</span> = <span class="hljs-title" style="box-sizing: border-box;">UIAlertController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tip"</span>, message: message, preferredStyle: .Alert)</span>
  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addAction</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ok"</span>, style: .Default, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 点击完成后,可以做相应处理,最后再回调js端
    completionHandler(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>)
  }))</span>
  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addAction</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cancel"</span>, style: .Cancel, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 点击取消后,可以做相应处理,最后再回调js端
    completionHandler(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>)
  }))</span>

  <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">presentViewController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(alert, animated: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>, completion: nil)</span>
}

<span class="hljs-title" style="box-sizing: border-box;">func</span> <span class="hljs-title" style="box-sizing: border-box;">webView</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: (String?) -> Void)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">alert</span> = <span class="hljs-title" style="box-sizing: border-box;">UIAlertController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: prompt, message: defaultText, preferredStyle: .Alert)</span>

  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addTextFieldWithConfigurationHandler</span> { <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(textField: UITextField)</span> -></span> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    textField.textColor = UIColor.redColor()
  }
  alert.addAction<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ok"</span>, style: .Default, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
     <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 处理好之前,将值传到js端
    completionHandler(alert.textFields![<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].text!)
  }))</span>

  <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">presentViewController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(alert, animated: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>, completion: nil)</span>
}

<span class="hljs-title" style="box-sizing: border-box;">func</span> <span class="hljs-title" style="box-sizing: border-box;">webViewDidClose</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">print</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(__FUNCTION__)</span>
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>

WKScriptMessageHandler

接下来,我们看看WKScriptMessageHandler,这个是注入js名称,在js端通过window.webkit.messageHandlers.{InjectedName}.postMessage()方法来发送消息到native。我们需要遵守此协议,然后实现其代理方法,就可以收到消息,并做相应处理。这个协议只有一个方法:

<code class="hljs go has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// MARK: - WKScriptMessageHandler</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">func</span> userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
  <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(message.body)
  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果在开始时就注入有很多的名称,那么我们就需要区分来处理</span>
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> message.name == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AppModel"</span> {
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"message name is AppModel"</span>)
  }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

这个方法是相当好的API,我们给js注入一个名称,就会自动转换成js的对象,然后就可以发送消息到native端。

WKNavigationDelegate

还有一个非常关键的代理WKNavigationDelegate,这个代理有很多的代理方法,可以控制页面导航。

其调用顺序为: 
1、这个代理方法是用于处理是否允许跳转导航。对于跨域只有Safari浏览器才允许,其他浏览器是不允许的,因此我们需要额外处理跨域的链接。

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 决定导航的动作,通常用于处理跨域的链接能否导航。WebKit对跨域进行了安全检查限制,不允许跨域,因此我们要对不能跨域的链接
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 单独处理。但是,对于Safari是允许跨域的,不用这么处理。
func webView<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void)</span> {
    <span class="hljs-title" style="box-sizing: border-box;">print</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(__FUNCTION__)</span>

    <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">hostname</span> = <span class="hljs-title" style="box-sizing: border-box;">navigationAction</span>.<span class="hljs-title" style="box-sizing: border-box;">request</span>.<span class="hljs-title" style="box-sizing: border-box;">URL</span>?.<span class="hljs-title" style="box-sizing: border-box;">host</span>?.<span class="hljs-title" style="box-sizing: border-box;">lowercaseString</span>

    <span class="hljs-title" style="box-sizing: border-box;">print</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(hostname)</span>
    // 处理跨域问题
    <span class="hljs-title" style="box-sizing: border-box;">if</span> <span class="hljs-title" style="box-sizing: border-box;">navigationAction</span>.<span class="hljs-title" style="box-sizing: border-box;">navigationType</span> == .<span class="hljs-title" style="box-sizing: border-box;">LinkActivated</span> && !<span class="hljs-title" style="box-sizing: border-box;">hostname</span>!.<span class="hljs-title" style="box-sizing: border-box;">containsString</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">".baidu.com"</span>)</span> {
      // 手动跳转
      <span class="hljs-title" style="box-sizing: border-box;">UIApplication</span>.<span class="hljs-title" style="box-sizing: border-box;">sharedApplication</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>.<span class="hljs-title" style="box-sizing: border-box;">openURL</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(navigationAction.request.URL!)</span>

      // 不允许导航
      <span class="hljs-title" style="box-sizing: border-box;">decisionHandler</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(.Cancel)</span>
    } <span class="hljs-title" style="box-sizing: border-box;">else</span> {
      <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">progressView</span>.<span class="hljs-title" style="box-sizing: border-box;">alpha</span> = 1.0

      <span class="hljs-title" style="box-sizing: border-box;">decisionHandler</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(.Allow)</span>
    }
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

2、开始加载页面内容时就会回调此代理方法,与UIWebViewdidStartLoad功能相当

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">__FUNCTION__</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

3、决定是否允许导航响应,如果不允许就不会跳转到该链接的页面。

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, decidePolicyForNavigationResponse navigationResponse: WKNavigationResponse, decisionHandler: (WKNavigationResponsePolicy) -> Void)</span> {
    <span class="hljs-title" style="box-sizing: border-box;">print</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(__FUNCTION__)</span>
    <span class="hljs-title" style="box-sizing: border-box;">decisionHandler</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(.Allow)</span>
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

4、Invoked when content starts arriving for the main frame.这是API的原注释。也就是在页面内容加载到达mainFrame时会回调此API。如果我们要在mainFrame中注入什么JS,也可以在此处添加。

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView(webView: WKWebView, didCommitNavigation navigation: WKNavigation!) {
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">__FUNCTION__</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

5、加载完成的回调

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">__FUNCTION__</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

如果加载失败了,会回调下面的代理方法:

<code class="hljs lua has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView(webView: WKWebView, didFailNavigation navigation: WKNavigation!, withError <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">error</span>: NSError) {
  <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(__FUNCTION__)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

其实在还有一些API,一般情况下并不需要。如果我们需要处理在重定向时,需要实现下面的代理方法就可以接收到。

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView(webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">__FUNCTION__</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

如果我们的请求要求授权、证书等,我们需要处理下面的代理方法,以提供相应的授权处理等:

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webView<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)</span> {
    <span class="hljs-title" style="box-sizing: border-box;">print</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(__FUNCTION__)</span>
    <span class="hljs-title" style="box-sizing: border-box;">completionHandler</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(.PerformDefaultHandling, nil)</span>
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

当我们终止页面加载时,我们会可以处理下面的代理方法,如果不需要处理,则不用实现之:

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func webViewWebContentProcessDidTerminate(webView: WKWebView) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">__FUNCTION__</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

源代码

具体代码已经发布到github:https://github.com/CoderJackyHuang/WKWebViewTestDemo

总结

苹果已经向我们提供了WKWebView,拥有UIWebView的所有功能,且还提供更多的功能,明示是为了替代UIWebView,但是WKWebView要在ios8.0之后才能使用,因此,如果我们使用Swift来开发应用,兼容版本从8.0开始时,可以直接使用WKWebView

我们可以发现,苹果提供了更多简便的方式让native与js交互更加方便,通过让native注入名称,然后在js端自动转换成js的对象,就可以在js端通过对象的方式来发送消息到native端。如此一来,就简化了js与native的交互了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值