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

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

WKWebView新特性

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

准备工作

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

 
1
2
3
 
Webkit
 

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

其初始化方法有:

 
1
2
3
4
5
 
)
)
)
 

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
?
 
// 9.0以后才支持  
)
?
 
// 通常用于加载本地HTML或者JS
?
    
// 9.0以后才支持
)
WKNavigation
 

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

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

创建WKWebView

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

 
1
2
3
 
WKUIDelegate
 

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
// 创建一个webiview的配置项
)
    
// Webview的偏好设置
)
10
true
// 默认是不能通过JS自动打开窗口的,必须通过用户交互才能打开
false
    
// 通过js与webview内容交互配置
)
    
// 添加一个JS到HTML中,这样就可以直接在JS中调用我们添加的JS方法
,
// 在载入时就添加JS
// 只添加到mainFrame中
)
    
// 添加一个名称,就可以在JS通过这个名称发送消息:
// window.webkit.messageHandlers.AppModel.postMessage({body: 'xxx'})
)
 

创建对象并遵守代理:

 
1
2
3
4
5
6
 
)
 
self
self
 

加载我们的本地HTML页面:

 
1
2
3
4
5
 
)
)
;
 

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

 
1
2
3
4
5
6
7
8
9
 
)
width
)
)
    
)
)
 

 

页面前进、后退

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
 
{
{
)
}
}
  
{
{
)
}
}
 

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

WKWebView的KVO

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

 
1
2
3
4
5
6
 
// 监听支持KVO的属性
)
)
)
 

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
// MARK: - KVO
{
{
)
{
title
{
)
)
}
  
// 已经完成加载时,我们就可以做我们的事了
{
// 手动调用JS代码
;
in
)
}
    
in
;
)
}
}
 

 

WKUIDelegate

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 
// MARK: - WKUIDelegate
// 这个方法是在HTML中调用了JS的alert()方法时,就会回调此API。
// 注意,使用了`WKWebView`后,在JS端调用alert()就不会在HTML
// 中显示弹出窗口。因此,我们需要在此处手动弹出ios系统的alert。
{
)
in
// We must call back js
)
)
  
)
}
 
{
)
in
// 点击完成后,可以做相应处理,最后再回调js端
)
)
in
// 点击取消后,可以做相应处理,最后再回调js端
)
)
  
)
}
 
{
)
  
in
)
}
in
// 处理好之前,将值传到js端
)
)
  
)
}
 
{
)
}
 

 

WKScriptMessageHandler

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

 
1
2
3
4
5
6
7
8
9
10
 
// MARK: - WKScriptMessageHandler
{
)
// 如果在开始时就注入有很多的名称,那么我们就需要区分来处理
{
)
}
}
 

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

WKNavigationDelegate

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

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
// 决定导航的动作,通常用于处理跨域的链接能否导航。WebKit对跨域进行了安全检查限制,不允许跨域,因此我们要对不能跨域的链接
// 单独处理。但是,对于Safari是允许跨域的,不用这么处理。
{
)
        
lowercaseString
        
)
// 处理跨域问题
{
// 手动跳转
)
      
// 不允许导航
)
{
1.0
      
)
}
}
 

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

 
1
2
3
4
5
 
{
)
}
 

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

 
1
2
3
4
5
6
 
{
)
)
}
 

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

 
1
2
3
4
5
 
{
)
}
 

5、加载完成的回调

 
1
2
3
4
5
 
{
)
}
 

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

 
1
2
3
4
5
 
{
)
}
 

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

 
1
2
3
4
5
 
{
)
}
 

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

 
1
2
3
4
5
6
 
{
)
)
}
 

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

 
1
2
3
4
5
 
{
)
}
 

 

源代码

具体代码已经发布到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的交互了。

 

相关文章:

  • 2021-05-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2018-01-10
  • 2022-01-15
  • 2018-04-21
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-18
相关资源
相似解决方案