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 的基本使用)