为了解决UIWebView加载速度慢、占用内存大的问题,苹果在iOS8.0之后推出了WKWebView以替代之,在使用WKWebView前先引入<WebKit/WebKit.h>框架。
WKWebView属性
WKWebView在原有基础上额外添加了几个属性如下:
// 浏览器配置;
@property (nonatomic, readonly, copy) WKWebViewConfiguration *configuration;
// 历史访问列表;
@property (nonatomic, readonly, strong) WKBackForwardList *backForwardList;
// 网页加载进度;
@property (nonatomic, readonly) double estimatedProgress;
WKWebView代理
WKWebView可以同时设置WKNavigationDelegate和WKUIDelegate两个代理,代理方法也有所改变如下:
#pragma mark - WKNavigationDelegate
// 在发送请求前的操作;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {}
// 在收到响应后的操作;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {}
// 在页面重指向时的操作;
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {}
// 页面准备加载;
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {}
// 页面开始加载;
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {}
// 页面完成加载;
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {}
// 页面加载失败;
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {}
// 页面跳转失败;
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {}
#pragma mark - WKUIDelegate
// 创建新的WebView;
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {}
// 拦截警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {}
// 拦截确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {}
// 拦截提示框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler {}
此外WKWebView新增了根据文件加载WebView的方法:
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL NS_AVAILABLE(10_11, 9_0);
WebViewJavascriptBridge实现交互
在项目中使用WebViewJavascriptBridge先添加OC代码如下:
WKWebView* webView = [[NSClassFromString(@"WKWebView") alloc] initWithFrame:self.view.bounds];
webView.navigationDelegate = self;
[self.view addSubview:webView];
// 设置允许桥接
[WKWebViewJavascriptBridge enableLogging];
// 初始化桥接对象并设置代理
_bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView];
[_bridge setWebViewDelegate:self];
// 注册函数testObjcCallback引用JS
[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"testObjcCallback called: %@", data);
responseCallback(@"Response from testObjcCallback");
}];
// 回调函数testJavascriptHandler供JS引用
[_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];
[self renderButtons:webView];
[self loadExamplePage:webView];
然后在HTML文件中添加js代码如下:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
OC引用JS
OC中注册函数:
[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"testObjcCallback called: %@", data);
responseCallback(@"Response from testObjcCallback");
}];
JS中实现回调函数:
setupWebViewJavascriptBridge(function(bridge) {
bridge.callHandler('testObjcCallback', {'foo': 'bar'}, function(response) {
// 该函数为js中声明的函数;
log('JS got response', response)
})
})
JS引用OC
JS中注册函数:
bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
log('ObjC called testJavascriptHandler with', data)
var responseData = { 'Javascript Says':'Right back atcha!' }
log('JS responding with', responseData)
responseCallback(responseData)
})
OC中实现回调并传值:
[_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];
以上就是WebViewJavascriptBridge与WKWebView的基本交互使用。