优点:WebKit 使用Nitro JavaScript引擎,webview可以和Safari加载一样快。加载网页占用的内存大大优化。高达60fps的滚动刷新频率及内置手势。开放了更多API给开发者(14个类、3个协议);
使用:首先引入库
#import <WebKit/WebKit.h>
初始化:WKWebViewConfiguration class wkwebview的基本配置类
WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init]; 先实例化配置类 以前UIWebView的属性有的放到了这里
_wkwebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0.0f, screen_width, screen_height) configuration:configuration];
新的属性:
_wkwebView.allowsBackForwardNavigationGestures =YES;//打开网页间的滑动返回
_wkwebView.allowsLinkPreview = YES;//允许预览链接
backForwardList 中包含backList(访问过未返回的地址) forwardList(访问过已返回的地址)currentItem(当前访问的地址)
wkwebview提供了KVO属性 可以用来获取加载进度(estimatedProgress) URL(URL)、TITLE(title)是否变化、是否可以前进或后退
[_wkwebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];//注册observer拿到加载进度
wkwebview除了后退:goBack 前进: goForward 方法外 还提供了reload方法 刷新当前页面 以及stopLoading 停止刷新
加载h5页面和UIWebView相似:[_wkwebView loadRequest:[NSURLRequest requestWithURL:url]];
代理:
//WKNavigationDelegate
//发送请求前决定是否允许跳转
/*
typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {
WKNavigationActionPolicyCancel,不允许
WKNavigationActionPolicyAllow, 允许
} NS_ENUM_AVAILABLE(10_10, 8_0);
*/
发生请求前是否允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
decisionHandler(WKNavigationActionPolicyAllow);
NSLog(@"发送请求前 allow跳转");
}
//接收到服务器响应后决定是否允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
{
decisionHandler(WKNavigationResponsePolicyAllow);
NSLog(@"接收到响应后 allow跳转");
}
//接收到服务器跳转响应后调用
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
{
NSLog(@"tiaozhuan");
}
//开始加载页面
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
{
NSLog(@"开始加载页面");
}
//加载页面数据完成
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
NSLog(@"加载页面完成");
NSLog(@"backlist ===%@",webView.backForwardList.backList);访问过未返回的页面
NSLog(@"forwordlst==%@",webView.backForwardList.forwardList);访问过已返回的页面
NSLog(@“url===%@",webView.backForwardList.currentItem.URL);当前访问的页面
在这里可以拿到web页的相关信息 做一些操作
}
//接收数据
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
NSLog(@"接收数据中");
}
//加载失败
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
{
NSLog(@"页面加载失败");
}
//在这个方法里实现注册的供js调用的oc方法
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
js native 交互
}
WKUIDelegate 页面中有调用了js的alert、confirm、prompt方法,应该实现下面这几个代理方法,然后在原来这里调用native的弹出窗,因为使用WKWebView后,HTML中的alert、confirm、prompt方法调用是不会再弹出窗口了,只是转化成ios的native回调代理方法(没咋用)。
JS NATIVE 交互:wkwebview提供了API实现js交互 不需要借助JavaScriptCore或者webJavaScriptBridge。使用WKUserContentController实现js native交互
oc代码:
首先需要在实例化WKWebViewConfiguration时 实例 WKUserContentController类并将其赋值给confiuration的属性:userContentController。
WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
//注册供js调用的方法
userContentController =[[WKUserContentController alloc]init];
[userContentController addScriptMessageHandler:self name:@“aaa”];//注册一个name为aaa的js方法
configuration.userContentController = userContentController;
configuration.preferences.javaScriptEnabled = YES;打开JavaScript交互 默认为YES
_wkwebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0.0f, screen_width, screen_height) configuration:configuration];
实现WKScriptMessageHandler的协议方法
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
userContentController 注册message的WKUserContentController;
message:js传过来的数据
id body:消息携带的信息 Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.
NSString *name:消息的名字 如aaa
//message.name js发送的方法名称
if([message.name isEqualToString:@"aaa"])
{
NSString * body = [message.body objectForKey:@“body"];
在这里写oc 实现协议的native方法 }
}
前端h5代码:前端需要用 window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据} 来给native发送消息
例如:
function secondClick() {
window.webkit.messageHandlers.aaa.postMessage({body: 'call js alert in js'});
}
**重要 如果注册了方法 [userContentController addScriptMessageHandler:self name:@“aaa"];
会导致hangler一直被引用 导致不走Delloc web页面无法释放 所以要在-(void)viewDidDisappear:(BOOL)animated中将messageHandler移除
[userContentController removeScriptMessageHandlerForName:@“aaa"]; 关闭web页时会释放内存。