一、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
- (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(^)(BOOLresult))completionHandler;
// 界面弹出输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt defaultText:(nullableNSString*)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重写
这里OC调用JS的时候是进行弹框处理,这里我在写的时候,很郁闷,方法可以调用过去,但是唯独js的alert方法调用没有效果,所以这里采用了输出到div的形式,并增加了一个clear按钮
WKWebView不支持nib文件,所以这里需要使用代码初始化并加载WebView
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];
NSString*filePath = [[NSBundlemainBundle] pathForResource:@"index"ofType:@"html"];
NSURL*baseURL = [[NSBundlemainBundle] bundleURL];
[self.wkWebView loadHTMLString:[NSStringstringWithContentsOfFile:filePath encoding:NSUTF8StringEncodingerror:nil] baseURL:baseURL];
OC端:
//1. JS调用OC 添加处理脚本
[user addScriptMessageHandler:self name:@"showName"];
// 在代理方法中处理对应事件
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",NSStringFromSelector(_cmd));
NSLog(@"%@",message.body);
if([message.name isEqualToString:@"showName"]) {
[selfshowMsg:@"您好,我是Jasmine"];
}
}
// 2. native调用js
- (IBAction)btnClick:(UIButton *)sender {
if(!self.wkWebView.loading) {
if(sender.tag == 234) {
[self.wkWebView evaluateJavaScript:@"alertName('小红')"completionHandler:nil];
}}else{
NSLog(@"the view is currently loading content");
}
}
JS端:
functionclear() {
document.getElementById('name').innerHTML =''
}
//OC调用JS的方法列表
//这里已经调用过来了 但是搞不明白为什么alert方法没有响应
functionalertName(msg) {
//alert('你好 ' + msg + ', 我也很高兴见到你')
document.getElementById('name').innerHTML ='你好 '+ msg +', 我也很高兴见到你'
}
//JS响应方法列表
functionbtnClick2() {
window.webkit.messageHandlers.showName.postMessage('xiao黄')
}