WKWebView在实际开发中的使用汇总

WKWebView支持ios8之后,优点:

1.更多的支持HTML5的特性

2.官方宣称的高达60fps的滚动刷新率以及内置手势

3.Safari相同的JavaScript引擎

4.占用更少的内存

一、基本使用

WKWebView有两个delegate,WKUIDelegateWKNavigationDelegate。WKNavigationDelegate主要处理一些跳转、加载处理操作,WKUIDelegate主要处理JS脚本,确认框,警告框等。因此WKNavigationDelegate更加常用。

1.导入头文件#import

2.相对应的使用方法:

备注:WKWebViewConfiguration和WKPreferences中有很多属性可以对webview初始化进行设置

 WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];

    config.selectionGranularity = WKSelectionGranularityDynamic;

    config.allowsInlineMediaPlayback = YES;

    WKPreferences *preferences = [WKPreferences new];

    //是否支持JavaScript

    preferences.javaScriptEnabled = YES;

    //不通过用户交互,是否可以打开窗口

    preferences.javaScriptCanOpenWindowsAutomatically = YES;

    config.preferences = preferences;

    WKWebView *webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight - 64) configuration:config];

    [self.view addSubview:webview];


    /* 加载服务器url的方法*/

    NSString *url = @"https://www.baidu.com";

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

    [webview loadRequest:request];


    webview.navigationDelegate = self;

    webview.UIDelegate = self;

遵循的协议和实现的协议方法:


#pragma mark - 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 decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{

    //允许跳转

    decisionHandler(WKNavigationActionPolicyAllow);

    //不允许跳转

    //decisionHandler(WKNavigationActionPolicyCancel);

}

/* 在收到响应后,决定是否跳转 */

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{


    NSLog(@"%@",navigationResponse.response.URL.absoluteString);

    //允许跳转

    decisionHandler(WKNavigationResponsePolicyAllow);

    //不允许跳转

    //decisionHandler(WKNavigationResponsePolicyCancel);

}

#pragma mark - WKUIDelegate

// 创建一个新的WebView

- (WKWebView*)webView:(WKWebView*)webView createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration forNavigationAction:(WKNavigationAction*)navigationAction windowFeatures:(WKWindowFeatures*)windowFeatures{

return[[WKWebViewalloc]init];

}

// 输入框

- (void)webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt defaultText:(nullableNSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void(^)(NSString* __nullableresult))completionHandler{ 

 completionHandler(@"http");

}// 确认框

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

 completionHandler(YES);

}

// 警告框

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

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

}

url中文处理


有时候我们加载的URL中可能会出现中文,需要我们手动进行转码,但是同时又要保证URL中的特殊字符保持不变,那么我们就可以使用下面的方法(方法放到了NSString中的分类中):

- (NSURL *)url{

#pragma clang diagnostic push

#pragma clang diagnostic ignored"-Wdeprecated-declarations"

    return [NSURL URLWithString:(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, (CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8))];

#pragma clang diagnostic pop

}

获取h5中的标题 和进度条


在初始化wenview时,添加两个观察者分别用来监听webview 的estimatedProgress和title属性:

webview.navigationDelegate = self;

webview.UIDelegate = self;


[webview addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];

[webview addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];

实现观察者的回调方法:


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    if ([keyPath isEqualToString:@"estimatedProgress"]) {

//进度条设置

        if ([change[@"new"] floatValue] <[change[@"old"] floatValue]) {

            return;

        }


//进度条设置        if ([change[@"new"]floatValue] == 1.0) {

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{


//进度条设置

            });

        }

    }else if ([keyPath isEqualToString:@"title"]){

//标题设置

    }

}

添加userAgent信息


在Appdelegate中添加一个WKWebview的属性,启动app时直接,为该属性添加userAgent:

- (void)setUserAgent {

    _webView = [[WKWebView alloc] initWithFrame:CGRectZero];

    [_webView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {

        if (error) { return; }

        NSString *userAgent = result;

        if (![userAgent containsString:@"/mobile-iOS"]) {

            userAgent = [userAgent stringByAppendingString:@"/mobile-iOS"];

            NSDictionary *dict = @{@"UserAgent": userAgent};

            [TKUserDefaults registerDefaults:dict];

        }

    }];

}

原生JS交互

(一)JS调用原生方法

在WKWebView中实现与JS的交互还需要实现另外一个代理方法:WKScriptMessageHandler

#pragma mark - WKScriptMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController

      didReceiveScriptMessage:(WKScriptMessage *)message


备注:JS只能向原生传递一个参数,所以如果有多个参数需要传递,可以让JS传递对象或者JSON字符串即可。


(二)原生调用JS方法

[webview evaluateJavaScript:“JS语句” completionHandler:^(id _Nullable data, NSError * _Nullable error) {


 }];

你可能感兴趣的:(WKWebView在实际开发中的使用汇总)