WKWebView的使用
本篇文章的例子是我的一个Demo,我直接复制的.m文件,没有分开写,可能你只是部分需要,需要自己手动去摘取,不全面,以后我会追加的
#import "ViewController.h" #import <Masonry.h> #import <WebKit/WebKit.h> @interface ViewController ()<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler> @property(nonatomic,strong)WKWebView *webView; //设置加载进度条 @property (nonatomic,strong) UIProgressView *progressView; @end @implementation ViewController - (UIProgressView *)progressView{ if (!_progressView) { _progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault]; // 设置进度条的色彩 [_progressView setTrackTintColor:[UIColor colorWithRed:240.0/255 green:240.0/255 blue:240.0/255 alpha:1.0]]; _progressView.progressTintColor = [UIColor orangeColor]; } return _progressView; } -(WKWebView *)webView{ if(!_webView){ //WKWebViewConfiguration配置文件 WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; //允许视频播放 config.allowsAirPlayForMediaPlayback = YES; // 允许在线播放 config.allowsInlineMediaPlayback = YES; // 允许可以与网页交互,选择视图 config.selectionGranularity = YES; // web内容处理池 config.processPool = [[WKProcessPool alloc] init]; // 是否支持记忆读取 config.suppressesIncrementalRendering = YES; //自定义配置,一般用于 js调用oc方法(OC拦截URL中的数据做自定义操作) WKUserContentController * userContentController = [[WKUserContentController alloc]init]; // 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除 这里是监听的时间方法,成功了之后执行WKScriptMessageHandler协议方法 [userContentController addScriptMessageHandler:self name:@"shareIOS"]; [userContentController addScriptMessageHandler:self name:@"closeWebViewIOS"]; config.userContentController = userContentController; _webView = [[WKWebView alloc]initWithFrame:CGRectZero configuration:config]; [_webView sizeToFit];//适应你设定的尺寸 // _webView.allowsBackForwardNavigationGestures = YES;//开启手势触摸 // 设置代理 _webView.navigationDelegate = self; _webView.UIDelegate = self; } return _webView; } - (void)viewDidLoad { [super viewDidLoad]; self.navigationController.navigationBarHidden = YES; [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.xxxxx.com?a=b"]]]; [self.view addSubview:self.webView]; [self.webView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.offset(0); make.size.equalTo(self.view); make.top.offset(-20); }]; [self.webView addSubview:self.progressView]; [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.right.offset(0); make.height.offset(2); }]; // 给webview添加监听 [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) { [self.progressView setAlpha:1.0f]; [self.progressView setProgress:self.webView.estimatedProgress animated:YES]; if (self.webView.estimatedProgress >= 1.0f) { [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{ [self.progressView setAlpha:0.0f]; } completion:^(BOOL finished) { [self.progressView setProgress:0.0f animated:YES]; }]; } }else{ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } #pragma mark ================ WKUIDelegate ================ // 警告框 -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{ NSLog(@"------------------------------------------------------------runJavaScriptAlertPanelWithMessage"); UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"警告框" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(); }]]; [self presentViewController:alert animated:YES completion:NULL]; } // 确认框 -(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{ NSLog(@"------------------------------------------------------------runJavaScriptConfirmPanelWithMessage"); UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"确认框" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(YES); }]]; [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { completionHandler(NO); }]]; [self presentViewController:alert animated:YES completion:NULL]; } // 输入框 -(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{ NSLog(@"------------------------------------------------------------runJavaScriptTextInputPanelWithPrompt"); UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"输入框" preferredStyle:UIAlertControllerStyleAlert]; [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.textColor = [UIColor redColor]; }]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler([[alert.textFields lastObject] text]); }]]; [self presentViewController:alert animated:YES completion:NULL]; } // webview关闭时回调 - (void)webViewDidClose:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0){ } // 默认预览元素调用 - (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo { NSLog(@"-----默认预览元素调用"); return YES; } // 返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。 - (nullable UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray<id <WKPreviewActionItem>> *)previewActions { NSLog(@"----返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。"); return self; } // 允许应用程序向它创建的视图控制器弹出 - (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController { NSLog(@"----允许应用程序向它创建的视图控制器弹出"); } // 显示一个文件上传面板。completionhandler完成处理程序调用后打开面板已被撤销。通过选择的网址,如果用户选择确定,否则为零。如果不实现此方法,Web视图将表现为如果用户选择了取消按钮。 - (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> * _Nullable URLs))completionHandler { NSLog(@"----显示一个文件上传面板"); } #pragma mark ================ WKScriptMessageHandler ================ //拦截执行网页中的JS方法 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ //服务器固定格式写法 window.webkit.messageHandlers.名字.postMessage(内容); //客户端写法 message.name isEqualToString:@"名字"] // message.name是方法名字 message.body方法的参数 NSLog(@"------------------------:%@ %@",message.name,message.body); if ([message.name isEqualToString:@"shareIOS"]) { //这里写事件 }else if ([message.name isEqualToString:@"closeWebViewIOS"]){ //这里写事件 } } - (void)dealloc{ [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"shareIOS"]; [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"closeWebViewIOS"]; [self.webView removeObserver:self forKeyPath:@"estimatedProgress"]; [self.webView setNavigationDelegate:nil]; [self.webView setUIDelegate:nil]; } #pragma mark ================ WKNavigationDelegate ================ // 1 在发送请求之前,决定是否跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSString *urlStr = navigationAction.request.URL.absoluteString; NSLog(@"1-------在发送请求之前,决定是否跳转 -->%@",urlStr); // if([urlStr hasPrefix:@"http:"]){ // decisionHandler(WKNavigationActionPolicyAllow);如果跳转使用这个 // }else{ // decisionHandler(WKNavigationActionPolicyCancel);如果不跳转使用这个 // } decisionHandler(WKNavigationActionPolicyAllow); } // 2 页面开始加载时调用 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { NSLog(@"2-------页面开始加载时调用"); } // 3 在收到响应后,决定是否跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { /// 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转 NSLog(@"3-------在收到响应后,决定是否跳转---:"); decisionHandler(WKNavigationResponsePolicyAllow); } // 4 当内容开始返回时调用 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { NSLog(@"4-------当内容开始返回时调用"); } // 5 页面加载完成之后调用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { NSLog(@"5-------页面加载完成之后调用"); } // 6 页面加载失败时调用 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation { NSLog(@"6-------页面加载失败时调用"); } // 接收到服务器跳转请求之后调用 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation { NSLog(@"-------接收到服务器跳转请求之后调用"); } // 数据加载发生错误时调用 - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error { NSLog(@"----数据加载发生错误时调用"); } // 需要响应身份验证时调用 同样在block中需要传入用户身份凭证 - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler { //用户身份信息 NSLog(@"----需要响应身份验证时调用 同样在block中需要传入用户身份凭证"); NSURLCredential *newCred = [NSURLCredential credentialWithUser:@"" password:@"" persistence:NSURLCredentialPersistenceNone]; // 为 challenge 的发送方提供 credential [[challenge sender] useCredential:newCred forAuthenticationChallenge:challenge]; completionHandler(NSURLSessionAuthChallengeUseCredential,newCred); } // 进程被终止时调用 - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { NSLog(@"----------进程被终止时调用"); } @end
以上是webview给OC传值,如果OC给webview给传值
//需要传递的数据 NSMutableDictionary *dic = [NSMutableDictionary new]; dic[@"token"] = @"11111"; NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:(NSJSONWritingPrettyPrinted) error:nil]; NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSString *js = [NSString stringWithFormat:@"window.iOSInfo = %@", jsonStr]; //传输的数据 WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:(WKUserScriptInjectionTimeAtDocumentStart) forMainFrameOnly:YES]; [self.configuration.userContentController addUserScript:script];
webview调用js的方法
NSDictionary *dic = @{ @"username": @"lpp",@"sex": @"女"}; NSString *source = [NSString stringWithFormat:@"jsMethod.setUserInfo(%@)", [dic toJSONString]]; [self.webView evaluateJavaScript:source completionHandler:^(id _Nullable callbackData, NSError * _Nullable error) { if (error) { NSLog(@"evaluate js setUserInfo fucntion error %@", error); return; } }];