WKWebView基本使用

一、基本的使用方法

<p>介绍:
       WKWebView是苹果推出的框架,性能比UIWebView更优。
首先上DEMO

WKWebView有两个delegate,WKUIDelegateWKNavigationDelegate

WKNavigationDelegate主要处理一些跳转、加载处理操作,

WKUIDelegate主要处理JS脚本,确认框,警告框等。因此WKNavigationDelegate更加常用。</p>

    // 1.配置环境
    WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
    userContentController =[[WKUserContentController alloc]init];
    configuration.userContentController = userContentController;
    wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:configuration];
    
    // 2.注册方法(必要设置,不然WKWebView会无法释放)
    WKDelegateController * delegateController = [[WKDelegateController alloc]init];
    delegateController.delegate = self;
    // 有添加一定有移除,成对出现
    [userContentController addScriptMessageHandler:delegateController  name:@"NativeMethod"];
    
    [self.view addSubview:wkWebView];
    
    wkWebView.UIDelegate = self;
    wkWebView.navigationDelegate = self;
    
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
    // 根据URL创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setTimeoutInterval:15];
    [wkWebView loadRequest:request];

常用的代理方法

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{

        NSLog(@"%@",navigationResponse.response.URL.absoluteString);
        //允许跳转
        decisionHandler(WKNavigationResponsePolicyAllow);
        //不允许跳转
        //decisionHandler(WKNavigationResponsePolicyCancel);
    }

    // 在发送请求之前,决定是否跳转
    -(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{

        NSLog(@"%@",navigationAction.request.URL.absoluteString);
        //允许跳转
        decisionHandler(WKNavigationActionPolicyAllow);
        //不允许跳转
        //decisionHandler(WKNavigationActionPolicyCancel);
    }

WKUIDelegate

    // 创建一个新的WebView
    -(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{

        return [[WKWebView alloc]init];
    }

    // 输入框
    -(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{

        completionHandler(@"http");
    }

    // 确认框
    -(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{

        completionHandler(YES);
    }

    // 警告框
    -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{

        NSLog(@"%@",message);
        completionHandler();
    }

    -(void)dealloc{

        //这里需要注意,前面增加过的方法一定要remove掉。
        [userContentController removeScriptMessageHandlerForName:@"NativeMethod"];
    }

WKScriptMessageHandler

    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

        NSLog(@"name:%@\\\\n body:%@\\\\n frameInfo:%@\\\\n",message.name,message.body,message.frameInfo);
    }


// 创建新的控制器设置代理(解决不能释放的问题)
    @protocol WKDelegate <NSObject><br>
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
    @end

    @interface WKDelegateController : UIViewController <WKScriptMessageHandler>
    @property (weak , nonatomic) id<WKDelegate> delegate;
    @end

    .m文件中的实现

    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

        if ([self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
            [self.delegate userContentController:userContentController didReceiveScriptMessage:message];
        }
    }

关于session 同步 cookies的问题

#### 1.基本配置
    NSMutableString *cookies = [NSMutableString string];
    WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:[cookies copy]
                                                         injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                      forMainFrameOnly:NO];
    [userContentController addUserScript:cookieScript];
    
    // 一下两个属性是允许H5视屏自动播放,并且全屏,可忽略
    configuration.allowsInlineMediaPlayback = YES;
    configuration.mediaPlaybackRequiresUserAction = NO;
    // 全局使用同一个processPool
    configuration.processPool = [[WKWebKitSupport sharedSupport] processPool];
    configuration.userContentController = userContentController;

#### 2.保存到本地
    // 在收到响应后,决定是否跳转<br>
    -(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{

        NSLog(@"%@",navigationResponse.response.URL.absoluteString);
        NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
        // 获取cookie,并设置到本地
        NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
        for (NSHTTPCookie *cookie in cookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }

        //允许跳转
        decisionHandler(WKNavigationResponsePolicyAllow);
        //不允许跳转
        //decisionHandler(WKNavigationResponsePolicyCancel);
    }

 #### 3.在开始请求时注入

    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableString *cookies = [NSMutableString string];
    NSMutableURLRequest *requestObj = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

    // 一般都只需要同步JSESSIONID,可视不同需求自己做更改
    NSString * JSESSIONID;
    // 获取本地所有的Cookie
    NSArray *tmp = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
        for (NSHTTPCookie * cookie in tmp) {
            if ([cookie.name isEqualToString:@"JSESSIONID"]) {
                JSESSIONID = cookie.value;
                break;
            }
        }
     if (JSESSIONID.length) {
          // 格式化Cookie
          [cookies appendFormat:@"JSESSIONID=%@;",JSESSIONID];
      }
    // 注入Cookie
    [requestObj setValue:cookies forHTTPHeaderField:@"Cookie"];
    // 加载请求
    [self.wk_webView loadRequest:requestObj];

新增拨打电话和弹窗

    // 在发送请求之前,决定是否跳转<br>
    -(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{

        NSLog(@"%@",navigationAction.request.URL.absoluteString);
        // 拨打电话

        NSURL *URL = navigationAction.request.URL;
        NSString *scheme = [URL scheme];
        UIApplication *app = [UIApplication sharedApplication];
        // 打电话
        if ([scheme isEqualToString:@"tel"]) {
            if ([app canOpenURL:URL]) {
                [app openURL:URL];
                // 一定要加上这句,否则会打开新页面
                decisionHandler(WKNavigationActionPolicyCancel);
                return;
            }
        }
        // 打开appstore
        if ([URL.absoluteString containsString:@"ituns.apple.com"]) {
            if ([app canOpenURL:URL]) {
                [app openURL:URL];
                decisionHandler(WKNavigationActionPolicyCancel);
                return;
            }
        }

        //允许跳转
        decisionHandler(WKNavigationActionPolicyAllow);
        //不允许跳转
        //decisionHandler(WKNavigationActionPolicyCancel);
    }

    #### 警告框
    -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{

        NSLog(@"%@",message);
        //  js 里面的alert实现,如果不实现,网页的alert函数无效  ,
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            completionHandler();
        }]];
        [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
            completionHandler();
        }]];

        [self presentViewController:alertController animated:YES completion:^{}];
        // 要实现
    //    completionHandler();
    }

    #### 确认框

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

        //  js 里面的alert实现,如果不实现,网页的alert函数无效  ,
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            completionHandler(YES);
        }]];
        [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
            completionHandler(NO);
        }]];

        [self presentViewController:alertController animated:YES completion:^{}];

    }

适配HTML5页面的问题

    // 内容视图自适应大小
    NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
    WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
    [userContentController addUserScript:wkUScript];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 为何使用WKWebView App开发过程中不可避免的会用到加载网页,从iOS2开始,我们一直使用的是UIWebV...
    辰牧殇阅读 989评论 0 1
  • Starting in iOS 8.0 and OS X 10.10, use WKWebView to add ...
    笑忘书丶阅读 2,991评论 0 3
  • 随说 : 最近有个需求,是将公司的一个内网的页面嵌套在app中作为一个模块.这不是很简单的webView请求一下就...
    travin阅读 30,846评论 26 73
  • 现在大部分的app只支持iOS8以上的系统了,在接入H5时可以只管最新的WKWebView了。 WKWebView...
    L小杰阅读 17,294评论 6 33
  • 前言 关于UIWebView的介绍,相信看过上文的小伙伴们,已经大概清楚了吧,如果有问题,欢迎提问。 本文是本系列...
    CoderLF阅读 8,943评论 2 12