首先OC里要和JS去交互,先行引入头文件#import
同样的,创建一个和屏幕大小的webView用于渲染HTML的页面,
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"index"
ofType:@"html"];
NSString * htmlCont = [NSString stringWithContentsOfFile:htmlPath
encoding:NSUTF8StringEncoding
error:nil];
self.webView.delegate = self;
[self.webView loadHTMLString: htmlCont baseURL:baseURL];
接下来写了一段蹩脚的HTML代码如下:
index.html
OC与JS交互
![](test.jpg)
小方块
将以上代码放到浏览器中渲染,只能看到几个按钮,一个破图片,点击的话也只有第一个弹框有反应,其他的都反应,因为内在逻辑实现的是按钮点击是有OC代码来反馈以及调用,比如弹起键盘,弹起原生的弹窗,收起键盘...打开系统相机相册等操作.
1. OC里调用JS的函数
一般这种情况是直接监听JS定义的函数
#pragma mark- 戳按钮,OC监听获取JS传过来的参数 [JS调用OC]
- (void)js_ocCallBack{
JSContext *js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
js[@"wgb_iOSHookJSButtonClick"] = ^(){
NSArray *args = [JSContext currentArguments];
NSString *arg = [args.firstObject toString];
NSLog(@"arg = %@",arg);
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"JS调用OC,JS传过来的参数是" message: arg delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil];
[alertView show];
});
};
}
//JS里的代码是这样的:
function secondClick(index) {
wgb_iOSHookJSButtonClick(index);
}
///三个`button` `onclick`调用 `secondClick(1)` ,`secondClick(2)` `secondClick(3)`这样子,然后JS走index, OC 调用`wgb_iOSHookJSButtonClick `,获取到参数值就是JS传过去的index,每次点击只传一个值.
2. JS里调用OC的函数
比如说JS调用原生的键盘啊,相机相册啥的...
#pragma mark- 弹起键盘
- (void)alertKeyboard{
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"jsCallOCAlertKeyboard"] = ^(){
///这个方法名和前端的同学约定好就ok的
dispatch_async(dispatch_get_main_queue(), ^{
UITextField *textfiled = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 10)];
[self.view addSubview: textfiled];
textfiled.hidden = YES;
[textfiled becomeFirstResponder];
});
};
}
#pragma mark- 退出原生键盘
- (void)wgb_keyboardResignFirstResponder{
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"wgb_keyboardResignFirstResponder"] = ^(){
dispatch_async(dispatch_get_main_queue(), ^{
[self.view endEditing:YES];
});
};
}
#pragma mark- 指定一个方法去调用 相机/相册 选择图片
- (void)js_callOCPhotoPickerImage{
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"iOSImageUpLoad"] = ^(){
dispatch_async(dispatch_get_main_queue(), ^{
[self.manager quickAlertSheetPickerImage];
});
};
}
以上这几个函数在网页加载完毕的时候就可以直接调用的
// 加载完成开始监听js的方法
- (void)webViewDidFinishLoad:(UIWebView *)webView{
JSContext *jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
jsContext[@"iosDelegate"] = self;
jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception){
context.exception = exception;
NSLog(@"获取 self.jsContext 异常信息:%@",exception);
};
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
[self js_ocCallBack];
[self oc_jsCallBack];
[self alertKeyboard];
[self wgb_keyboardResignFirstResponder];
[self js_callOCPhotoPickerImage];
return YES;
}
Github Demo地址