苹果在iOS8时候推出WKWebView来替代UIWebView,并且使用Nitro JavaScript引擎,这意味着所有第三方浏览器运行JavaScript将会跟safari一样快对比UIWebView来说
优点1,在性能、稳定性、功能方面有很大提升
2,允许JavaScript的Nitro库加载并使用(UIWebView中限制);
3,支持了更多的HTML5特性;
4,高达60fps的滚动刷新率以及内置手势;
5,将UIWebViewDelegate与UIWebView重构成了14类与3个协议
缺点
1,WkWebView不再支持页面缓存
2,WkWebView不可以实现NSURLProtocol拦截
3,不支持JavaScriptCore进行交互
4,不支持nib也就是不能在storyboard创建初始化
一、初始化WkWebView并且设置代理
//设置WKWebview
- (void)setWKWebView{
//添加js交互对象
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addScriptMessageHandler:self name:@"OCAlert"];
// WKWebView的配置
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;
//初始化webView
_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 100, kScreenWidth, kScreenHeight - 100) configuration:configuration];
[self.view addSubview:_webView];
NSString *path = [[NSBundle mainBundle] pathForResource:@"h5" ofType:@"html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
}
#pragma WKUIDelegate
/// 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
}
/// 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
}
/// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
completionHandler();
//可解决UIWebView下有时弹出框显示网址的缺陷
[self createAlertTitle:webView.title Msg:message];
}
三、实现 WKNavigationDelegate代理,可控制页面是否跳转,一些https相关证书配置也在此代理中设置
// 接收到服务器跳转请求之后调用 (服务器端redirect),不一定调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
}
// 3 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
decisionHandler(WKNavigationResponsePolicyAllow);
}
/// 1 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
// 在发送请求之前,决定是否跳转
decisionHandler(WKNavigationActionPolicyAllow);
NSString *title = webView.title;
NSLog(@"标题是%@",title);
}
/// 2 页面开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
}
/// 4 开始获取到网页内容时返回
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
}
/// 5 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
}
/// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
}
四、测试html代码
<html>
<header>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>h5</title>
<script type="text/javascript">
function jsAlert(Msg)
{
alert(Msg);
}
function JStoOC(){
window.webkit.messageHandlers.OCAlert.postMessage("这是OC弹出框");
}
</script>
</header>
<body>
<br/>
<h2> 这里是一个HTML页面 </h2>
<br/>
<form name="myform" οnsubmit="return JStoOC()">
<button type="submit">去调用OC弹出框</button>
</form>
</body>
</html>
五、实现WKScriptMessageHandler代理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
//window.webkit.messageHandlers.<name>.postMessage(<messageBody>) js调用
//WKUserContentController有两个核心方法,也是它的核心功能。添加供js调用oc的桥梁。这里的name对应WKScriptMessage中的name,多数情况下我们认为它就是方法名 body即为参数
//WKScriptMessage就是js通知oc的数据。其中有两个核心属性用的很多。
// 方法名
NSString *methods = [NSString stringWithFormat:@"%@:", message.name];
SEL selector = NSSelectorFromString(methods);
// 调用方法
if ([self respondsToSelector:selector]) {
[self performSelector:selector withObject:message.body];
}
}
五、处理js与OC相互调用的方法
- (void)OCAlert:(NSString *)body{
[self createAlertTitle:@"OC" Msg:body];
}
- (void)createAlertTitle:(NSString *)title Msg:(NSString *)msg{
UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
[alertVC addAction:action];
[self presentViewController:alertVC animated:YES completion:nil];
}
#pragma mark OC调用js
- (void)ocCallJS{
NSString *jsStr1 = [NSString stringWithFormat:@"jsAlert('这是JS方法弹出框')"];
[self.webView evaluateJavaScript:jsStr1 completionHandler:^(id _Nullable data, NSError * _Nullable error) {
if (error) {
NSLog(@"错误:%@", error.localizedDescription);
}
}];
}
六、demo地址http://download.csdn.net/detail/u010067452/9746373
介绍 一个强大的JS与OC交互的框架:https://github.com/marcuswestin/WebViewJavascriptBridge