WKWebView|WKWebView 的基本使用

WKWebView比UIWebView的好处,不多说
直接上代码
webview的控制器

@interface ILWebActTestViewController ()@property (strong, nonatomic) G_Nav *nav; @property (nonatomic ,strong) WKWebView * actWKWebView; @property (nonatomic,strong)WKUserContentController * contentController; @end@implementation ILWebActTestViewController- (void)viewDidLoad {[super viewDidLoad]; [self initUI]; [self initWebView]; }- (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; self.tabBarController.tabBar.hidden = YES; }-(void)initUI{ self.view.backgroundColor = [UIColor whiteColor]; self.nav= [G_Nav new]; self.nav.backStr = @"返回"; [self.nav setG_Nav:self.view]; self.nav.bgView.backgroundColor= COLOR_RGBA(38, 184, 242, 1.0); self.nav.tittleLabel.textColor =[UIColor whiteColor]; self.nav.tittleLabel.text = @"搞事情"; self.nav.delegate = self; }#pragma mark - 初始化WebView -(void)initWebView{NSMutableURLRequest*urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0]; //要给request加上当前登录信息的cookies,要不然身份验证通不过 [urlRequest addValue:[self readCurrentCookie] forHTTPHeaderField:@"Cookie"]; //使用WKUserContentController实现js native交互,简单的说就是先注册约定好的方法,然后再调用WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc] init]; _contentController = [[WKUserContentController alloc] init]; configuration.userContentController = _contentController; //kWeakself; //注册方法 //下面这句代码造成无法释放内存。(ps:试了下用weak指针还是不能释放,不知道是什么原因。)因此还需要进一步改进,正确的写法是用一个新的controller来处理,新的controller再绕用delegate绕回来 //[contentController addScriptMessageHandler:weakSelf name:@"Share"]; ILWebWkDelegateController *delegateController = [[ILWebWkDelegateController alloc] init]; delegateController.delegate = self; [_contentController addScriptMessageHandler:delegateController name:@"Share"]; _actWKWebView = [[WKWebView alloc ] initWithFrame:CGRectZero configuration:configuration]; [self.view addSubview:_actWKWebView]; [_actWKWebView mas_makeConstraints:^(MASConstraintMaker *make) {make.top.mas_equalTo(kGNavHeight); make.left.right.bottom.equalTo(self.view); }]; [_actWKWebView loadRequest:urlRequest]; _actWKWebView.UIDelegate = self; _actWKWebView.navigationDelegate = self; }#pragma mark - G_NavDelegate -(void)clickBackBt:(UIButton*)sender{ [self.navigationController popViewControllerAnimated:YES]; }#pragma mark - WKUIDelegate#pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{NSLog(@"加载数据的时候的页面开始加载的时候失败"); }- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation{NSLog(@"当页面开始返回内容"); }- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{NSLog(@"当页面加载完成后调用"); }- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{ NSLog(@"在接收数据的过程中加载失败"); }// 接收到服务器跳转请求之后调用 - (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); }#pragma mark - WKWeakDelegate - (void)EYUserContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{NSLog(@"name:%@\\\\n body:%@\\\\n frameInfo:%@\\\\n",message.name,message.body,message.frameInfo); if ([message.name isEqualToString:@"Share"]) { [self ShareWithInformation:message.body]; } }#pragma mark - WKScriptMessageHandler - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{NSLog(@"name:%@\\\\n body:%@\\\\n frameInfo:%@\\\\n",message.name,message.body,message.frameInfo); if ([message.name isEqualToString:@"Share"]) { [self ShareWithInformation:message.body]; }}#pragma mark - 获取当前cookies/** 以前UIWebView会自动去NSHTTPCookieStorage中读取cookie,但是WKWebView并不会去读取,因此导致cookie丢失以及一系列问题,解决方式就是在request中手动帮其添加上 但是这只能解决第一次进入的cookie问题,如果页面内跳转(a标签等)还是取不到cookie,因此还要再加代码 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { //取出cookie NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; //js函数 NSString *JSFuncString = @"function setCookie(name,value,expires)\ {\ var oDate=new Date(); \ oDate.setDate(oDate.getDate()+expires); \ document.cookie=name+'='+value+'; expires='+oDate+'; path=/'\ }\ function getCookie(name)\ {\ var arr = document.cookie.match(new RegExp('(^| )'+name+'=([^; ]*)(; |$)')); \ if(arr != null) return unescape(arr[2]); return null; \ }\ function delCookie(name)\ {\ var exp = new Date(); \ exp.setTime(exp.getTime() - 1); \ var cval=getCookie(name); \ if(cval!=null) document.cookie= name + '='+cval+'; expires='+exp.toGMTString(); \ }"; //拼凑js字符串 NSMutableString *JSCookieString = JSFuncString.mutableCopy; for (NSHTTPCookie *cookie in cookieStorage.cookies) { NSString *excuteJSString = [NSString stringWithFormat:@"setCookie('%@', '%@', 1); ", cookie.name, cookie.value]; [JSCookieString appendString:excuteJSString]; } //执行js [webView evaluateJavaScript:JSCookieString completionHandler:nil]; } @return cookies 字符串 */ - (NSString*)readCurrentCookie{NSArray *cookies =[ILUser cookies]; NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary]; [cookieProperties setObject:[cookies objectAtIndex:0] forKey:NSHTTPCookieName]; [cookieProperties setObject:[cookies objectAtIndex:1] forKey:NSHTTPCookieValue]; [cookieProperties setObject:[cookies objectAtIndex:3] forKey:NSHTTPCookieDomain]; [cookieProperties setObject:[cookies objectAtIndex:4] forKey:NSHTTPCookiePath]; if (cookieProperties == nil) { return nil; }else{ NSHTTPCookieStorage*cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; NSMutableString *cookieString = [[NSMutableString alloc] init]; for (NSHTTPCookie*cookie in [cookieJar cookies]) { [cookieString appendFormat:@"%@=%@; ",cookie.name,cookie.value]; } //删除最后一个“;” [cookieString deleteCharactersInRange:NSMakeRange(cookieString.length - 1, 1)]; return cookieString; } }#pragma mark - 处理分享 - (void)ShareWithInformation:(NSDictionary *)dic { if (![dic isKindOfClass:[NSDictionary class]]) { return; } [self showThirdShareView:[dic objectForKey:@"url"]]; } - (void)showThirdShareView:(NSString *)shareURL { NSArray *iamgeArr = @[@"ic_pyq",@"ic_wxchat",@"ic_zone",@"ic_qq"]; NSArray *titleArr = @[@"朋友圈",@"微信",@"QQ空间",@"QQ"]; NSString *shareTitle = @"我有一个官方出品的陕旅版英语APP推荐给你,电子课本免费用!"; NSString *sahreDescription = @"官方出品,教材配套,权威内容,让我的英语学习so easy!"; UIImage *shareImage = [UIImage imageNamed:@"shareIcon"]; //分享页面 ThirdShareView *thirdShareView = [[ThirdShareView alloc] initWithTitle:titleArr AndWithImage:iamgeArr AndOffset:NO]; thirdShareView.selectBlock=^(NSString *platForm){ //分享对应platframe ThirdShareModel *thirdModel = [[ThirdShareModel alloc] init]; if ([platForm isEqualToString:@"QQ"]) { [thirdModel qqShare:qqSceneFriend sharetype:contentTypeWeb shareText:sahreDescription image:shareImage title:shareTitle URL:shareURL]; }else if ([platForm isEqualToString:@"QQ空间"]) { [thirdModel qqShare:qqSceneZone sharetype:contentTypeWeb shareText:sahreDescription image:shareImage title:shareTitle URL:shareURL]; }else if ([platForm isEqualToString:@"微信"]) { [thirdModel wxShare:wxSceneSession sharetype:contentTypeWeb shareText:sahreDescription image:shareImage title:shareTitle URL:shareURL]; }else if ([platForm isEqualToString:@"朋友圈"]) { [thirdModel wxShare:wxSceneTimeline sharetype:contentTypeWeb shareText:sahreDescription image:shareImage title:shareTitle URL:shareURL]; } }; UIApplication *applaction = [UIApplication sharedApplication]; [applaction.keyWindow addSubview:thirdShareView]; }-(void)dealloc{ //这里需要注意,前面增加过的方法一定要remove掉。 [_contentController removeScriptMessageHandlerForName:@"Share"]; }

为了防止循环引用的代理控制代码
.m
@interface ILWebWkDelegateController ()@end@implementation ILWebWkDelegateController- (void)viewDidLoad { [super viewDidLoad]; } - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ if ([self.delegate respondsToSelector:@selector(EYUserContentController:didReceiveScriptMessage:)]) { [self.delegate EYUserContentController:userContentController didReceiveScriptMessage:message]; } }@end

.h
@protocol WKWeakDelegate - (void)EYUserContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message; @end@interface ILWebWkDelegateController : UIViewController@property (weak , nonatomic) id delegate; @end

【WKWebView|WKWebView 的基本使用】参考

    推荐阅读