WKWebView要实现JS调用OC方法,重点就是三项:
- 必须在html中预留接口,格式是固定的:window.webkit.messageHandlers.ActionName.postMessage('parameter');
- 配置WKWebViewConfiguration,并通过WKUserContentController注册html中预留的方法;
- 实现WKScriptMessageHandler协议的- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message方法。
@interface ViewController ()<WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
@property(nonatomic, strong) WKWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.webView];
[self loadLocalHtml];
}
- (void)loadLocalHtml {
NSString *path = [[NSBundle mainBundle] pathForResource:@"myHtml.html" ofType:nil];
NSURL *fileURL = [NSURL fileURLWithPath:path];
[self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
}
//WKJavaScriptDelegate
// 2、JS调用OC
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"PrintHelloWorld"]) {
NSLog(@"响应方法为:PrintHelloWorld");
} else if ([message.name isEqualToString:@"CallUser"]) {
NSLog(@"响应方法为:CallUser");
} else if ([message.name isEqualToString:@"PopupAlert"]) {
NSLog(@"响应方法为:PopupAlert");
} else {
NSLog(@"响应方法为:nothing");
}
}
//使用了WKWebView后,在JS端调用alert()是不会在HTML中显式弹出窗口,是我们需要在该方法中手动弹出iOS系统的alert的
//该方法中的message参数就是我们JS代码中alert函数里面的参数内容
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alertView = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
[alertView addAction:[UIAlertAction actionWithTitle:@"Sure" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//一定要调用下这个block
//API说明:The completion handler to call after the alert panel has been dismissed
completionHandler();
}]];
[self presentViewController:alertView animated:YES completion:nil];
}
- (WKWebView *)webView {
if (!_webView) {
_webView = [[WKWebView alloc] init];
//以下代码适配大小
NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *userController = [[WKUserContentController alloc] init];
[userController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = userController;
// 1、JS调用OC
[userController addScriptMessageHandler:self name:@"PrintHelloWorld"];
[userController addScriptMessageHandler:self name:@"CallUser"];
[userController addScriptMessageHandler:self name:@"PopupAlert"];
_webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:wkWebConfig];
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
}
return _webView;
}
@end
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JS与OC交互</title>
<!-- 定义js函数 -->
<script type="text/javascript">
// 3、JS调用OC
<!-- 如果是WKWebview,必须在html中预留接口,格式是固定的:-->
<!-- window.webkit.messageHandlers.ActionName.postMessage('parameter');-->
function printHelloWorldAction(){
window.webkit.messageHandlers.PrintHelloWorld.postMessage('printHelloWorld');
}
function callUserAction(){
window.webkit.messageHandlers.CallUser.postMessage('callUser');
}
function popupAlertAction(){
window.webkit.messageHandlers.PopupAlert.postMessage('popupAlert');
}
</script>
</head>
<body>
<!-- 创建一个按钮,点击就调用 printHelloWorld() 方法 -->
<button onclick="printHelloWorldAction()">控制台打印</button>
<button onclick="callUserAction()">拨打电话</button>
<button onclick="popupAlertAction()">弹窗警告窗口</button>
</body>
</html>
复制代码