iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能、稳定性、功能大幅度提升,也更好的支持了HTML5的新特性。
一、WKWebView Framework
WKWebView的14个类与3个协议:
-
WKBackForwardList
: 之前访问过的 web 页面的列表,可以通过后退和前进动作来访问到。 -
WKBackForwardListItem
: webview 中后退列表里的某一个网页。 -
WKFrameInfo
: 包含一个网页的布局信息。 -
WKNavigation
: 包含一个网页的加载进度信息。 -
WKNavigationAction
: 包含可能让网页导航变化的信息,用于判断是否做出导航变化。 -
WKNavigationResponse
: 包含可能让网页导航变化的返回内容信息,用于判断是否做出导航变化。 -
WKPreferences
: 概括一个 webview 的偏好设置。 -
WKProcessPool
: 表示一个 web 内容加载池。 -
WKUserContentController
: 提供使用 JavaScript post 信息和注射 script 的方法。 -
WKScriptMessage
: 包含网页发出的信息。 -
WKUserScript
: 表示可以被网页接受的用户脚本。 -
WKWebViewConfiguration
: 初始化 webview 的设置。 -
WKWindowFeatures
: 指定加载新网页时的窗口属性。 -
WKWebsiteDataStore
: 包含网页数据存储和查找。 -
WKNavigationDelegate
: 提供了追踪主窗口网页加载过程和判断主窗口和子窗口是否进行页面加载新页面的相关方法。 -
WKUIDelegate
: 提供用原生控件显示网页的方法回调。 -
WKScriptMessageHandler
: 提供从网页中收消息的回调方法。
二、WKWebView中的三个代理方法
1. WKNavigationDelegate
该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转。
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2. WKUIDelegate
创建一个新的WKWebView
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
剩下三个代理方法全都是与界面弹出提示框相关的,针对于web界面的三种提示框(警告框、确认框、输入框)分别对应三种代理方法。
// 界面弹出警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
// 界面弹出确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
// 界面弹出输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
3. WKScriptMessageHandler
这个协议中包含一个必须实现的方法,这个方法是native与web端交互的关键,它可以直接将接收到的JS脚本转为OC或Swift对象。
// 从web界面中接收到一个脚本时调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
三、使用WKWebView
1.创建
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.preferences.minimumFontSize = 18;
self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2) configuration:config];
[self.view addSubview:self.wkWebView];
//加载本地HTML
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSURL *baseURL = [[NSBundle mainBundle] bundleURL];
[self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];
2.js调用oc
(1)先在HTML声明调用方法:
window.webkit.messageHandlers.showMobile.postMessage(data)
showMobile
:方法名
data
:js向oc传的参数,可为null
(2)在oc中注册需要的方法:
WKUserContentController *userCC = config.userContentController;
//JS调用OC 添加处理脚本 方法名必须和js里的方法一样
[userCC addScriptMessageHandler:self name:@"showMobile"];
(3)在WKScriptMessageHandler
代理中实现
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
if ([message.name isEqualToString:@"showMobile"])
{
// 实现你的需求
}
}
2.oc调用js
(1)在HTML注册所需方法:
function alertMobile() {
}
(2)oc中调用:
[self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
//TODO
NSLog(@"%@ %@",response,error);
}];