专栏首页移动端开发WKWebView的使用与JS交互详细解读

WKWebView的使用与JS交互详细解读

前言:

    WKWebView 这是在iOS8.0之后增加的一个比UIWebView更加完善和强大的控件!看网上关于它的博客也是有许多的了,从各个方面总结一下这个WKWebView看网上说它主要是为了和JS做好交互产生的,我们也会相应的尝试一下。就先从它基本的说起!

一:和UIWebView相比它的不同处

1:和JS更好的做交互,也支持H5的一些新特性

2:加载进度条(下面会演示)

3:性能高,加载变得更快更可靠

二:从加载一张网页开始

1:使用这个WKWebView是要#import <WebKit/WebKit.h>

2:遵守协议,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler(最后这个协议留神一下就知道视为JS准备的)

3:加载百度试一下

WKWebView * webviwe = [[WKWebView alloc]initWithFrame:self.view.bounds];
[webviwe loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
[self.view addSubview:webviwe];   

三:说说加载进度条

这个是利用KVO模式写的,WKWebView有一个  estimatedProgress 属性,利用它来监听加载的进度,下面的进度打印出来了,但具体的进度条就没有写出来,你们可以自己写一个 UIProgressView 放在导航栏的下面。

 // estimatedProgress  WKWebView 这个属性添加观察者
 [webviwe addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];    
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if (object == webviwe && [keyPath isEqualToString:@"estimatedProgress"] ) {
        // 这里就不写进度条了,把加载的进度打印出来,进度条可以自己加上去!
        CGFloat newProgress = [[change objectForKey:NSKeyValueChangeNewKey] floatValue];
        NSLog(@"%f",newProgress);  
    }
}

看看打印的进度信息:

2016-08-11 14:44:17.237 RaectiveCocoaTest[21054:252565] 页面开始加载

2016-08-11 14:44:17.724 RaectiveCocoaTest[21054:252565] 0.300000

2016-08-11 14:44:17.726 RaectiveCocoaTest[21054:252565] 内容正在加载当中

2016-08-11 14:44:18.000 RaectiveCocoaTest[21054:252565] 0.719984

2016-08-11 14:44:18.196 RaectiveCocoaTest[21054:252565] 1.000000

2016-08-11 14:44:18.196 RaectiveCocoaTest[21054:252565] 页面加载完成

四:详细的方法使用说明以及注释

详解 WKNavigationDelegate 代理方法,我们把它的代理方法使用代码以及注意点全都写出来,注意看下面的注释!

#pragma mark - WKNavigationDelegate
// 页面加载开始  Provisional临时的
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    NSLog(@"页面开始加载");   
}
// 加载内容
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
    NSLog(@"内容正在加载当中");
}
// 页面加载完成
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    NSLog(@"页面加载完成");
}
//  页面加载失败
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"页面加载失败");
}
// 接收到服务器重新配置请求之后再执行
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
{
    
}
// API是根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{   
    NSURLRequest * request = navigationAction.request;
    NSLog(@"%@",request.URL.absoluteString);
    
    // 判断请求头是否是 https://www.baidu.com 如果是就不在请求加载跳转
    WKNavigationActionPolicy  actionPolicy = WKNavigationActionPolicyAllow;
    if ([request.URL.absoluteString hasPrefix:@"https://www.baidu.com"]) {
        
        actionPolicy = WKNavigationActionPolicyCancel;
        
    }
    // 必须这样执行,不然会崩
    decisionHandler(actionPolicy);
}
/**
 *   
 要是允许跳转,看下面的打印内容,注意加载的顺序!和下面的方法进行比较,区分它们的不同之处
 2016-08-11 13:55:12.628 RaectiveCocoaTest[18155:211964] https://www.baidu.com/
 2016-08-11 13:55:12.629 RaectiveCocoaTest[18155:211964] 页面开始加载
 2016-08-11 13:55:13.725 RaectiveCocoaTest[18155:211964] 内容正在加载当中
 2016-08-11 13:55:14.681 RaectiveCocoaTest[18155:211964] 页面加载完成
 *
 */
// API是根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转
-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    NSLog(@"%@",navigationResponse.response);
    /**
     *  判断响应的数据里面的URL是https://www.baidu.com/开头的,要是就不让它加载跳转
     */
    WKNavigationResponsePolicy responsePolicy = WKNavigationResponsePolicyAllow;
    if ([navigationResponse.response.URL.absoluteString hasPrefix:@"https://www.baidu.com/"]) {
        
        responsePolicy = WKNavigationResponsePolicyCancel;
    }
    decisionHandler(responsePolicy);
}
/**
 *  
 响应返回的的URL包含了https://www.baidu.com/,所以页面是不能被加载的,要是能加载就有下面的打印信息,注意和上面方法的区分对比!
 2016-08-11 13:53:38.392 RaectiveCocoaTest[17961:209778] 页面开始加载
 2016-08-11 13:53:38.675 RaectiveCocoaTest[17961:209778] https://www.baidu.com/
 2016-08-11 13:53:38.678 RaectiveCocoaTest[17961:209778] 内容正在加载当中
 2016-08-11 13:53:38.936 RaectiveCocoaTest[17961:209778] 页面加载完成
 */

五:说说WKUIDelegate和JS的简单交互

先看看 WKUIDelegate里面的代理方法都是用来做什么的,我们一个一个的解释这几个代理方法;

// 创建方法,这个就不在多说了,重点放在下面几个
-(nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    return nil;
}

// ios 9 之后才有的方法
-(void)webViewDidClose:(WKWebView *)webView
{
    
}

下面这三个方法根据方法前面的字面意思就能区分记住!

runJavaScriptAlert 方法注意点

1.在JS端调用alert函数时,会触发此代理方法。

2.JS端调用alert时所传的数据可以通过message,打印message信息读取出JS端给你的信息。

3.在原生得到结果后,需要回调给JS,通过completionHandler 回调给JS

4.completionHandler 回调的参数和返回值都是空

/**
下面这三个方法根据前面的字面意思就能区分记住!
 */
// runJavaScriptAlert
// 在JS端调用alert函数时,会触发此代理方法。
// JS端调用alert时所传的数据可以通过message,打印message信息读取出JS端给你的信息。
// 在原生得到结果后,需要回调给JS,通过completionHandler 回调给JS
// completionHandler 回调的参数和返回值都是空
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert"message:@"JS调用alert"preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
    }]];
    
    [self presentViewController:alert animated:YES completion:NULL];
    NSLog(@"%@", message);
    
}

runJavaScriptTextInput 注意点

1.要求用户输入一段文字

3.在原生输入得到文本内容后,通过completionHandler回调给JS

4.大家注意这个回调的completionHandler参数是字符串

// runJavaScriptTextInput
// 要求用户输入一段文本
// 在原生输入得到文本内容后,通过completionHandler回调给JS 大家注意这个回调的completionHandler参数是字符串
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
{

}

runJavaScriptConfirmPane(ConfirmPane字面意思是确认框)

1.JS端调用confirm函数时,会触发此方法

2.通过message可以拿到JS端所传给我们数据

3.在iOS端显示原生alert得到YES/NO后,通过completionHandler回调给JS端

4.注意这个completionHandler回调的参数是BOOL类型的

-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
    
}

要有什么问题或者发现错误的地方,及时留言联系我,立马改正!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS 转场动画探究(一)

    什么是转场动画:        转场动画说的直接点就是你常见的界面跳转的时候看到的动画效果,我们比较常见的就是控制器之间的Push和Pop,还有Present和...

    Mr.RisingSun
  • iOS 转场动画探究(二)

    这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一) 接着上一篇写的内容:        上一篇iOS...

    Mr.RisingSun
  • iOS 转场动画探究(二)

    这篇文章是接着第一篇写的,要是有同行刚看到的话建议从前面第一篇看,这是第一篇的地址:iOS 转场动画探究(一)

    Mr.RisingSun
  • 加载第三方JS的各种姿势

    如果你的网站上面有很多第三方JS代码,那么“下载速度的不可控”很有可能导致你的网站会被拖慢。因为JS在执行的时候会影响到页面的DOM和样式等情况。浏览器在解析渲...

    mmzhou
  • 大周末的不多说,面试十点必看

    实事求是的讲,前端新人因为时间的关系,对于JavaScript的理解确实是无法面面具到,甚至有些知识点我讲的比较深入,但因为每个人的程度不同,依然无法做到当堂理...

    web前端教室
  • 【前端编程】加载第三方JS的各种姿势

    从网站开发者的角度来看,第三方JS相比第一方JS有如下几个不同之处: 下载速度不可控 JS地址域名与网站域名不同 文件内容不可控 不一定有强缓存(Cache-C...

    李海彬
  • IOS WebView控件详解

    概述 WebView就是一个内嵌浏览器控件,在iOS中主要有两种WebView:UIWebView和WKWebView,UIWebView是iOS2之后开始使用...

    xiangzhihong
  • WebRTC | Web服务器原理、Nodejs工作原理、Nodejs事件处理流程、V8引擎等要点解析

    凌川江雪
  • 进程和线程的区别和联系

    我们都知道计算机的核心是CPU,它承担了所有的计算任务,而操作系统是计算机的管理者,它负责任务的调度,资源的分配和管理,统领整个计算机硬件;应用程序是具有某种功...

    葆宁
  • 自己动手用electron+vue开发博客园文章编辑器客户端【二】

    在nwjs里,宿主页面与做过特殊标记的iframe页面(nwdisable nwfaketop和nwUserAgent)通信,并没有什么特别的地方

    liulun

扫码关注云+社区

领取腾讯云代金券