首先看下JS部分的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<script>
// 如果是使用UIWebView的话,使用这个测试调起原生暴露的方法
function callIosMethod() {
// log();
// logString('这个是传进来的字符串');
logWithCallBack('这是一个带回调的传进的字符串', function(params0,param1) {
var str = params0 + param1;
alert(str);
});
}
// WKWebView
function callWKMethod() {
// 注意,logWithCallBack为原生暴露的方法名,必须要与原生代码中的对应
// 参数部分可以通过postMessage的参数传递
window.webkit.messageHandlers.logWithCallBack.postMessage({"key" : "value", "callback" : "111"});
}
// 供原生调用的测试方法(理论来说,只要是在这里写的public方法,都算是暴露出来的方法,都可以调用)
function exportToIos() {
alert('iOS调起了JS方法');
}
function exportToIosWithArguement(arguement) {
alert(arguement);
}
function methodWithThreeArguements(arg1, arg2) {
alert(arg1 + arg2);
}
</script>
<style>
p {
background-color: #ff3333;
color: #fff;
padding: 10px, 10px;
display: inline-block;
}
</style>
</head>
<body>
<p onclick="callIosMethod()">我是个按钮</p>
<p onclick="callWKMethod()">测试WKWebView点这个<p/>
</body>
</html>
UIWebView部分代码
- (void)viewDidLoad {
[super viewDidLoad];
// 此处我的webView为xib拖得,省去了初始化webView的代码
// 加载本地html文件
NSString *path = @"/Users/liuxu/Desktop/H5学习代码/index.html";
NSURL *url = [NSURL fileURLWithPath:path];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
self.webView.delegate = self;
// 获取当前webview的JSContext
self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 暴露方法供H5调用
// 无参数
self.jsContext[@"log"] = ^(){
NSLog(@"hahhahahhaha");
};
// 一个参数
self.jsContext[@"logString"] = ^(NSString *str) {
NSLog(@"%@",str);
};
// 有回调
self.jsContext[@"logWithCallBack"] = ^(NSString *str, JSValue *value) {
NSLog(@"%@",str);
[value callWithArguments:@[@"1",@"2"]];
};
}
// 调用JS的方法
- (IBAction)callJS:(id)sender {
// 设置异常处理,此步骤不能省略
[self.jsContext setExceptionHandler:^(JSContext *context, JSValue *exception) {
}];
// 无参数
// [self.jsContext evaluateScript:@"exportToIos()"];
// 有参数
[self.jsContext evaluateScript:@"exportToIosWithArguement('lalala')"];
}
效果图如下
点击页面上的CallJS按钮.png
2.点击H5页面上的'我是个按钮',控制台输出'这是一个带回调的传进的字符串',随后触发回调部分的代码
点击我是个按钮.png
WKWebView部分代码
#import "WKWebViewController.h"
#import <WebKit/WebKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
@interface WKWebViewController () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
@property (strong, nonatomic) WKWebView *webView;
@end
@implementation WKWebViewController
- (void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
// 注入方法
[userContentController addScriptMessageHandler:self name:@"log"];
[userContentController addScriptMessageHandler:self name:@"logString"];
[userContentController addScriptMessageHandler:self name:@"logWithCallBack"];
configuration.userContentController = userContentController;
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
[self.view insertSubview:self.webView atIndex:0];
NSString *path = @"/Users/liuxu/Desktop/H5学习代码/index.html";
NSURL *url = [NSURL fileURLWithPath:path];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
// 调用JS暴露出的方法
- (IBAction)callJS:(id)sender {
NSString *js = @"exportToIos()";
[self.webView evaluateJavaScript:js completionHandler:nil];
}
// 用于拦截alert方法,实现该方法后可以js可以正常调用alert方法
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
// JS调用原生注入的方法后会走该方法,可以在此处判断并进行相应操作
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSDictionary *dict = message.body;
if ([message.name isEqualToString:@"log"]) {
}
else if ([message.name isEqualToString:@"logString"]) {
} else if ([message.name isEqualToString:@"logStringWithCallBack"]) {
}
}
- (void)dealloc {
[self.webView.configuration.userContentController removeAllUserScripts];
}
@end