参考:http://blog.csdn.net/reylen/article/details/46437517
WKWebView相对于UIWebView强大了很多,内存的消耗相对少了,所提供的接口也丰富了。
0.WKWebView创建
0.1属性
打开左划回退功能self.webView.allowsBackForwardNavigationGestures=YES;
WKWebView里有一个属性estimatedProgress,可以拿到进度。 但是并没有delegate来好让你更新进度控件。 所以一定要用进度的话,需要一个NSRunLoop
self.wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight-64-50-self.topViewH.constant)];
self.wkWebView.navigationDelegate = self;
self.wkWebView.UIDelegate = self;
[self.bWebView addSubview:self.wkWebView];
self.wkWebView.scrollView.scrollEnabled = NO;
self.wkWebView.allowsBackForwardNavigationGestures = NO;
1. navigationDelegate
- (void)webView:(WKWebView*)webViewdidStartProvisionalNavigation:(WKNavigation*)navigation {// 类似UIWebView的 -webViewDidStartLoad:页面开始加载时调用
NSLog(@"didStartProvisionalNavigation");[UIApplicationsharedApplication].networkActivityIndicatorVisible=YES;
}
- (void)webView:(WKWebView*)webViewdidCommitNavigation:(WKNavigation*)navigation {当内容开始返回时调用NSLog(@"didCommitNavigation");}
- (void)webView:(WKWebView*)webViewdidFinishNavigation:(WKNavigation*)navigation {// 类似 UIWebView 的 -webViewDidFinishLoad:页面加载完成之后调用
NSLog(@"didFinishNavigation");[selfresetControl];
if(webView.title.length>0) {
self.title= webView.title;
}
}
- (void)webView:(WKWebView*)webViewdidFailProvisionalNavigation:(WKNavigation*)navigationwithError:(NSError*)error {
// 类似 UIWebView 的- webView:didFailLoadWithError:页面加载失败时调用
NSLog(@"didFailProvisionalNavigation");
}
//页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{//// 接收到服务器跳转请求之后调用
NSLog(@"6------");
}
- (void)webView:(WKWebView*)webViewdecidePolicyForNavigationResponse:(WKNavigationResponse*)navigationResponsedecisionHandler:(void(^)(WKNavigationResponsePolicy))decisionHandler {//// 在收到响应后,决定是否跳转
decisionHandler(WKNavigationResponsePolicyAllow);
}
- (void)webView:(WKWebView*)webViewdecidePolicyForNavigationAction:(WKNavigationAction*)navigationActiondecisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {// 在发送请求之前,决定是否跳转
// 类似 UIWebView 的 -webView: shouldStartLoadWithRequest: navigationType:
NSLog(@"4.%@",navigationAction.request);
NSString*url = [navigationAction.request.URL.absoluteStringstringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)webView:(WKWebView*)webViewdidReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challengecompletionHandler:(void(^)(NSURLSessionAuthChallengeDisposition,NSURLCredential*))completionHandler {
}
2 UIDelegate
- (WKWebView*)webView(WKWebView*)webViewcreateWebViewWithConfiguration:(WKWebViewConfiguration*)configurationforNavigationAction:(WKNavigationAction*)navigationActionwindowFeatures:(WKWindowFeatures*)windowFeatures {
// 接口的作用是打开新窗口委托
[selfcreateNewWebViewWithURL:webView.URL.absoluteStringconfig:configuration];
returncurrentSubView.webView;
}
- (void)webView:(WKWebView*)webViewrunJavaScriptAlertPanelWithMessage:(NSString*)messageinitiatedByFrame:(WKFrameInfo*)framecompletionHandler:(void(^)())completionHandler
{// js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController*alertController = [UIAlertControlleralertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertControlleraddAction:[UIAlertActionactionWithTitle:@"确定"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction*action) {
completionHandler();
}]];
[selfpresentViewController:alertControlleranimated:YEScompletion:^{}];
}
- (void)webView:(WKWebView*)webViewrunJavaScriptConfirmPanelWithMessage:(NSString*)messageinitiatedByFrame:(WKFrameInfo*)framecompletionHandler:(void(^)(BOOL))completionHandler {
// js 里面的alert实现,如果不实现,网页的alert函数无效 ,
UIAlertController*alertController = [UIAlertControlleralertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertControlleraddAction:[UIAlertActionactionWithTitle:@"确定"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction*action) {
completionHandler(YES);
}]];
[alertControlleraddAction:[UIAlertActionactionWithTitle:@"取消"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction*action){
completionHandler(NO);
}]];
[selfpresentViewController:alertControlleranimated:YEScompletion:^{}];
}
- (void)webView:(WKWebView*)webViewrunJavaScriptTextInputPanelWithPrompt:(NSString*)promptdefaultText:(NSString*)defaultTextinitiatedByFrame:(WKFrameInfo*)framecompletionHandler:(void(^)(NSString*))completionHandler {
completionHandler(@"Client Not handler");
}
3. WKWebView 执行脚本方法
- (void)evaluateJavaScript:(NSString*)javaScriptStringcompletionHandler:(void(^)(id,NSError*))completionHand
completionHandler 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值
4. WKWebView 的Cookie问题
UIWebView 中会自动保存Cookie,如果登录了一次,下次再次进入的时候,会记住登录状态而在WKWebView中,并不会这样,WKWebView在初始化的时候有一个方法
- (instancetype)initWithFrame:(CGRect)frameconfiguration:(WKWebViewConfiguration*)configuration
通过这个方法,设置 configuration 让WKWebView知道登录状态,configuration 可以通过已有的Cookie进行设置,也可以通过保存上一次的configuration进行设置
例子一
WKWebView* webView =/*set up your webView*/
NSMutableURLRequest* request = [NSMutableURLRequestrequestWithURL:[NSURLURLWithString:@"http://example.com/index.html"]];
[requestaddValue:@"TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;"forHTTPHeaderField:@"Cookie"];
// use stringWithFormat: in the above line to inject your values programmatically
[webViewloadRequest:request];
例子二
WKUserContentController* userContentController = WKUserContentController.new;
WKUserScript* cookieScript = [[WKUserScriptalloc]
initWithSource:@"document.cookie = 'TeskCookieKey1=TeskCookieValue1';document.cookie = 'TeskCookieKey2=TeskCookieValue2';"
injectionTime:WKUserScriptInjectionTimeAtDocumentStartforMainFrameOnly:NO];
// again, use stringWithFormat: in the above line to inject your values programmatically
[userContentControlleraddUserScript:cookieScript];
WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.new;
webViewConfig.userContentController= userContentController;
WKWebView* webView = [[WKWebViewalloc]initWithFrame:CGRectMake(/*set your values
5.WKWebView与js通信
iOS 8 引入WKWebView,WKWebView不支持JavaScriptCore的方式但提供message handler的方式为JavaScript与Objective-C通信.
在Objective-C中使用WKWebView的以下方法调用JavaScript:
- (void)evaluateJavaScript:(NSString *)javaScriptString
completionHandler:(void (^)(id, NSError *))completionHandler
如果JavaScript代码出错, 可以在completionHandler进行处理.
在Objective-C中注册 message handler:
// WKScriptMessageHandler protocol?
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message
{
NSLog(@"Message: %@", message.body);
}
[userContentController addScriptMessageHandler:handler name:@"myName"];
在JavaScript将信息发给Objective-C:
// window.webkit.messageHandlers..postMessage();?
function postMyMessage()? {?
var message = { 'message' : 'Hello, World!', 'numbers' : [ 1, 2, 3 ] };?
window.webkit.messageHandlers.myName.postMessage(message);?
}