一. JavaScriptCore 简介
首先要区分JavaScriptCore 和 JavaScriptCore 框架:
JavaScriptCore框架是一个苹果在iOS7引入的框架,该框架让 Objective-C 和 JavaScript 代码直接的交互变得更加的简单方便。
而JavaScriptCore是苹果Safari浏览器的JavaScript引擎,JavaScriptCore在性能上也不输V8引擎了。
执行一段js代码:
JSContext *context = [[JSContext alloc]init];
JSValue*value = [contextevaluateScript:@"2+2"];
NSLog(@"%d",[valuetoInt32]);
JSContext:
JSContext 为JS代码的执行提供了上下文环境,通过jSCore执行的JS代码都得通过JSContext来执行。
JSValue:
JSValue 是对 JS 值的包装

oc执行一段js代码:
方式一:
test.js:
var factorial = function(l,r){ return l+r; };
oc代码:
NSString*path = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"js"];
NSString *valueString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
JSContext *context = [[JSContext alloc]init];
[context evaluateScript:valueString]; //载入js代码
JSValue*value = [context evaluateScript:@"factorial(2,3)"];
NSLog(@"%d",[valuetoInt32]); //输出:5
方式二:
。。。。
JSValue*func = context[@"factorial"];
JSValue*result = [funccallWithArguments:@[@3,@4]];
NSLog(@"%d",[resulttoInt32]); //输出7
注:JS中的object对象类型,对应到OC中就是字典类型,这种类似字典的下标方式不仅可以取值,也可以存值。不仅可以作用于Context,也可以作用与JSValue。
2.JavaScript 与 Objective-C 交互
JavaScript 与 Objective-C 交互主要通过2种方式,Block和JSExport
1.Block方式:
js代码:var colorMap = {
"red":254,
"green":100,
"blue":200,
};
var colorForWord =function(color){
//调用oc函数makeNSColor
return makeNSColor(color);
};
oc代码:JSContext *context = [[JSContext alloc]init];
context[@"makeNSColor"] = ^float(NSDictionary *colors){ //js中的函数对象相当于oc中的block
float r = [colors[@"red"] floatValue];
return r;
};
NSString*path = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"js"];
NSString *valueString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[context evaluateScript:valueString];
//js调用oc
JSValue *value = [context evaluateScript:@"colorForWord(colorMap)"];
NSLog(@"%f",[value toDouble]);
注意:
不要在Block中直接使用JSValue
不要在Block中直接使用JSContext
因为Block会强引用它里面用到的外部变量,如果直接在Block中使用JSValue的话,那么这个JSvalue就会被这个Block强引用,而每个JSValue都是强引用着它所属的那个JSContext的
2.JSExport方式
ViewController.h :
@protocol TestJSExport <JSExport>
- (void)testOC;
@end
@interface ViewController :UIViewController
@property (strong, nonatomic) JSContext *context;
@end
ViewController.m :
- (void)viewDidLoad {
[super viewDidLoad];
self.context= [[JSContextalloc]init];
self.context[@"native"] =self;
NSString*path = [[NSBundle mainBundle]pathForResource:@"JSCallOC" ofType:@"js"];
NSString *valueString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[self.contextevaluateScript:valueString];
}
- (void)testOC{
NSLog(@"test oc");
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{
[self.context evaluateScript:@"colorForWord()"];
}
JSCallOC.js :
var colorForWord =function(){
native.testOC();
};
JS调用OC系统类 :
自定义协议(UILabelJSExport) :
@protocol UILabelJSExport<JSExport>
@property(nonatomic,strong)NSString*text;
@end
JS调用OC系统类 :
- (void)jsCallOCSystemClass{
// 给系统类添加协议
class_addProtocol([UILabelclass],@protocol(UILabelJSExport));
// 创建UILabel
UILabel*label = [[UILabelalloc] initWithFrame:CGRectMake(50,50,100,100)]; [self.view addSubview:label];
JSContext *ctx = [[JSContext alloc] init];
// 就会在JS中生成label对象,并且用laebl引用
ctx[@"label"] = label;
// 利用JS给label设置文本内容
NSString*jsCode =@"label.text = 'Oh Year'";
[ctx evaluateScript:jsCode];
}