1.UIWebView占用的内存比WKWebView多不少,IOS8以后使用WKWebview。
2.在UIWebView中html中的alert、confirm、prompt会弹出窗口,但是在WKWebView中不会弹出了,转换成了ios中WKUIDelegate回调,WKUIDelegate主要处理与JS交互的,WKNavigationDelegate主要处理WKWebView的一些网页加载。
3.
//1.创建wkwebview的配置
WKWebViewConfiguration *configuration=[[WKWebViewConfigurationalloc] init];
userContent=[[WKUserContentControlleralloc] init];
//2.设置配置内容
configuration.userContentController=userContent;
webView=[[WKWebViewalloc] initWithFrame:CGRectZeroconfiguration:configuration];
//3.添加JS端调用的方法名
[userContentaddScriptMessageHandler:selfname:@"getClientMethod"];
// [userContent addScriptMessageHandler:self name:@"test"];
webView.navigationDelegate=self;
webView.UIDelegate=self;
[self.viewaddSubview:webView];
4.JS端的写法也有一些改变,
UIWebView中的写法为window.myObj.JsClick("StartBarcode")
WKWebView中的写法为
window.webkit.messageHandlers.getClientMethod.postMessage('{\"key\":\"haha\",\"key2\":\"value2\"}');
getClientMethod是方法名,'{\"key\":\"haha\",\"key2\":\"value2\"}'是一个json的参数
JS端调用会触发下面的回调:
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
NSLog(@"didReceiveScriptMessage==%@ ------ %@",message.name,message.body);
NSDictionary *dic=[selfjsonStringToDictionary:message.body];
NSLog(@"dic is %@ ",dic);
}
5.客户端调用JS端的方法:第一种是带参数的,第二种是不带参数的。
NSString *string=[NSStringstringWithFormat:@"usedByClient2(\"%@\")",@"999999"];
[webViewevaluateJavaScript:stringcompletionHandler:^(id object,NSError *error) {
NSLog(@"error is %@ ",error);
}];
NSString *string2=[NSStringstringWithFormat:@"usedByClient()"];
[webViewevaluateJavaScript:string2completionHandler:^(id object,NSError *error) {
NSLog(@"error is %@ ",error);
}];
6.页面销毁的时候需要把注册的方法移除
[userContentremoveScriptMessageHandlerForName:@"getClientMethod"];
但是由于注册了JS,此VC的dealloc方法不会调用,在这里面移除没有用,不会被执行,
在页面快消失的时候移除
-(void)viewWillDisappear:(BOOL)animated{
if([self.navigationController.viewControllersindexOfObject:self]==NSNotFound){
NSLog(@"clicked navigationbar back button");
[userContentremoveScriptMessageHandlerForName:@"getClientMethod"];
webView.UIDelegate=nil;
webView.navigationDelegate=nil;
}
},此时发现当注册的方法被移除了之后,页面销毁的时候dealloc方法被调用了。所以把注册的方法在dealloc中移除是不会执行的。
7.下面是一些回到的解释
#pragma mark navigationDelagate
/**
* 页面加载时调用
*/
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"didStartProvisionalNavigation==============");
}
//内容开始返回时
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
NSLog(@"didCommitNavigation==============");
}
//页面加载完时
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
NSLog(@"didFinishNavigation==============");
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"didFailProvisionalNavigation==============");
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"didReceiveServerRedirectForProvisionalNavigation==============");
}
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSLog(@"decidePolicyForNavigationResponse==============");
NSLog(@"%@",navigationResponse.response.URL.absoluteString);
//允许跳转
decisionHandler(WKNavigationResponsePolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationResponsePolicyCancel);
}
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
NSLog(@"decidePolicyForNavigationAction==============");
NSLog(@"%@",navigationAction.request.URL.absoluteString);
//允许跳转
decisionHandler(WKNavigationActionPolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationActionPolicyCancel);
}
#pragma mark - WKUIDelegate
//WKUIDelegate 页面中有调用了js的alert、confirm、prompt方法,应该实现下面这几个代理方法,然后在原来这里调用native的弹出窗,因为使用WKWebView后,HTML中的alert、confirm、prompt方法调用是不会再弹出窗口了,只是转化成ios的native回调代理方法
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
NSLog(@"createWebViewWithConfiguration==============");
return [[WKWebViewalloc]init];
}
// 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullableNSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
NSLog(@"runJavaScriptTextInputPanelWithPrompt==============");
completionHandler(@"http");
}
// 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
NSLog(@"runJavaScriptConfirmPanelWithMessage框==============");
completionHandler(YES);
}
// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
NSLog(@"runJavaScriptAlertPanelWithMessage==============");
NSLog(@"%@",message);
completionHandler();
}
#pragma mark JS端调用我们上面注册的方法时走的回调
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
NSLog(@"didReceiveScriptMessage==%@ ------ %@",message.name,message.body);
NSDictionary *dic=[selfjsonStringToDictionary:message.body];
NSLog(@"dic is %@ ",dic);
}