WKWebView 像一个应用程序内置的浏览器,用来显示可交互的网页。
一、WKWebView 基本使用
1、简单使用
// 初始化、布局
_webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:_webView];
// 设置代理
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
// 加载网页
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
2、WKNavigationDelegate 介绍和使用
// 页面开始加载时调用
- (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;
// 在请求发送之前,决定是否跳转。例如拦截 URL 决定是否打开链接。
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
// 如果是跳转目标是一个新的窗口页面
if (navigationAction.targetFrame == nil) {
[webView loadRequest:navigationAction.request];
}
// 打印链接
NSURL *URL = navigationAction.request.URL;
NSString *url = [URL absoluteString];
DebugLog(@"url = %@", url);
// 支付宝和微信
BOOL hasAlipay = [url hasPrefix:@"alipay://"] || [url hasPrefix:@"alipays://"] || [url hasPrefix:@"https://mclient.alipay.com"];
BOOL hasWechat = [url hasPrefix:@"weixin://"];
if (hasAlipay || hasWechat) {
[[UIApplication sharedApplication] openURL:URL options:@{} completionHandler:nil];
// 禁止跳转
decisionHandler(WKNavigationActionPolicyCancel);
} else {
// 允许跳转
decisionHandler(WKNavigationActionPolicyAllow);
}
}
3、常用方法
// 刷新页面
- (nullable WKNavigation *)reload;
// 显示上页面
- (nullable WKNavigation *)goBack;
// 显示下页面
- (nullable WKNavigation *)goForward;
// 显示指定页面
- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
二、OC 与 H5 交互
1、JS 调用 OC
WKUserContentController 对象负责注册 JS 方法,设置处理接收 JS 方法的代理,代理要遵守 WKScriptMessageHandler 协议。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[_webView.configuration.userContentController addScriptMessageHandler:self name:@"js_method_name"];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[_webView.configuration.userContentController removeScriptMessageHandlerForName:@"js_method_name"];
}
WKScriptMessageHandler 协议
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"js_method_name"]) {
// do something
}
}
WKScriptMessage 对象有两个重要属性
// JS 方法传递的参数
@property (nonatomic, readonly, copy) id body;
// JS 方法名称
@property (nonatomic, readonly, copy) NSString *name;
2、OC 调用 JS
WKWebView 提供以下API 可以直接调用 JS 方法。
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id,NSError *))completionHandler;
例如:
// 方法参数一般设置为 JSON 对应的字符串 JSONString
NSString *javaScriptString = [NSString stringWithFormat:@"js_method(\"%@\")", @"JSONString"];
[_webView evaluateJavaScript:javaScriptString completionHandler:^(id _Nullable responese, NSError * _Nullable error) {
}];