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 的基本使用】参考
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量