iOS的系统框架JavaScriptCore可以实现JS与OC互相通讯,本文就简单说下iOS与JS交互相互调用
1.凡事添加了JSExport协议的协议,所规定的方法变量等,就会对js开放,我们可以通过js调用到。
2.iOS调用js方法
方式一:
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
方式二:
- (JSValue *)evaluateScript:(NSString *)script;
方式三:
根据 .jsContext获取JSValue,执行- (JSValue *)callWithArguments:(NSArray *)arguments;
结合代码具体说一下:
一.简单地JS对象通过协议调用iOS方法
(1).创建协议
/首先创建一个实现了JSExport协议的协议@protocol TestJSObjectProtocol//此处我们测试几种参数的情况
-(void)TestNOParameter;
-(void)TestOneParameter:(NSString* )message;
@end
(2).遵守协议
自定义的SZKoclaJScontextModel类遵守TestJSObjectProtocol协议
(3).实现协议方法
-(void)TestNOParameter
{NSLog(@"this is ios TestNOParameter");}
-(void)TestOneParameter:(NSString *)message
{NSLog(@"this is ios TestOneParameter=%@",message);}
(4).在web加载完成后调用JS对象,触发协议方法
-(void)webViewDidFinishLoad:(UIWebView *)webView{
self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
/*****************说明**************
用model的原因是防止内存泄漏
很多demo是这样写的
self.jsContext[@"web"] = self;
但是这样写会造成循环引用,导致内存泄漏
****************/
SZKoclaJScontextModel *model = [SZKoclaJScontextModel new];
self.jsContext[@"testobject"]= model;
//同样我们也用刚才的方式模拟一下js调用方法
NSString *jsStr1=@"testobject.TestNOParameter()";
[ self.jsContext evaluateScript:jsStr1];
NSString *jsStr2=@"testobject.TestOneParameter('参数1')";
[ self.jsContext evaluateScript:jsStr2];
}
我们可以在控制台看到如下效果:
二.js调用iOS方法
(1).定义代理协议
@protocol SZKoclaJScontextModelDelegate-(void)share;
-(void)callBackTest;//这里的名字可以和JSExportDelegate不一致
@end
(2).添加代理属性
(3).遵循代理,并添加delegate
(4).实现代理方法
#pragma mark js调用iOS方法
-(void)share{
NSArray *args = [JSContext currentArguments];
[_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"shareCallback()"]];//方法回调成功弹出js的alert;
NSLog(@"%@",args );
}
三.iOS调用JS;
#pragma mark iOS调用js方法
-(void)btnJS:(id)sender{
//方式一
[_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"callCamera()"]];//弹出js的alert;
NSString *result = [_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"callBack(%@,%@)",@"123",@"456"]];
//方式二
JSValue *result1 = [self.jsContext evaluateScript:[NSString stringWithFormat:@"callBack(%@,%@)",@"123",@"789"]];//使用jsContext调用js方法回调成功弹出js的alert;
//方式三
JSValue *jsFunction = self.jsContext[@"callBack"];
JSValue *result2 = [jsFunction callWithArguments:@[@"345",@"123"]];//如果有参数,数组里面跟对应参数例如:@[@"123",@"ewqe"]
JSValue *result3 = [jsFunction callWithArguments:@[[NSNumber numberWithInt:123],[NSNumber numberWithInt:567]]];
NSLog(@"%@",result);
NSLog(@"%@",[result1 description]);
NSLog(@"%@",[result2 description]);
NSLog(@"%@",[result3 description]);
}
-(void)callCamera:(JSContext *)context{
context[@"callCamera"]=^() {
// NSArray *args = [JSContext currentArguments];//如果有参数,使用这种方法获取参数;
NSLog(@"callCamera");
_imagePickerController = [[UIImagePickerController alloc] init];
_imagePickerController.delegate = self;
_imagePickerController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
_imagePickerController.allowsEditing = YES;
_imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:_imagePickerController animated:YES completion:^{
} ] ; };
}
-(void)callBackTest{
NSArray *args = [JSContext currentArguments];
//方式一
[_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"shareCallback()"]];//使用webView回调成功弹出js的alert;
NSLog(@"%@",args );
//方式二
[self.jsContext evaluateScript:@"shareCallback()"];//使用jsContext调用js方法回调成功弹出js的alert;
//方式三
JSValue *jsFunction = self.jsContext[@"shareCallback"];
[jsFunction callWithArguments:@[]];//如果有参数,数组里面跟对应参数例如:@[@"123",@"ewqe"]
}
代码github