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;
}
}];
浙公网安备 33010602011771号