IOS UIWebView转WKWebView中的js交互问题

时间:2021-03-15 21:11:37

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 页面中有调用了jsalertconfirmprompt方法,应该实现下面这几个代理方法,然后在原来这里调用native的弹出窗,因为使用WKWebView后,HTML中的alertconfirmprompt方法调用是不会再弹出窗口了,只是转化成iosnative回调代理方法

// 创建一个新的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);

}