OC 调 JS 就是 OC给JS传值
JSContext
是运行 JavaScript 代码的环境。一个 JSContext
是一个全局环境的实例,如果你写过一个在浏览器内运行的 JavaScript,JSContext
类似于 window
。创建一个 JSContext
后,可以很容易地运行 JavaScript 代码来创建变量,做计算,甚至定义方法:
JSContext *context = [[JSContext alloc] init];
[context evaluateScript:@"var num = 5 + 5"];
[context evaluateScript:@"var names = ['Grace', 'Ada', 'Margaret']"];
[context evaluateScript:@"var triple = function(value) { return value * 3 }"];
JSValue *tripleNum = [context evaluateScript:@"triple(num)"];
代码的最后一行,任何出自
JSContext
的值都被包裹在一个JSValue
对象中。像 JavaScript 这样的动态语言需要一个动态类型,所以JSValue
包装了每一个可能的 JavaScript 值:字符串和数字;数组、对象和方法;甚至错误和特殊的 JavaScript 值诸如null
和undefined
。
JSValue
包括一系列方法用于访问其可能的值以保证有正确的 Foundation 类型,包括:
JavaScript Type | JSValue method | Objective-C Type | Swift Type |
---|---|---|---|
string | toString | NSString | String! |
boolean | toBool | BOOL | Bool |
number | toNumber toDouble toInt32 toUInt32 | NSNumber double int32_t uint32_t | NSNumber! Double Int32 UInt32 |
Date | toDate | NSDate | NSDate! |
Array | toArray | NSArray | [AnyObject]! |
Object | toDictionary | NSDictionary | [NSObject
: AnyObject]! |
Object | toObject toObjectOfClass: | custom type | custom type |
tripleNum
的值,只需使用适当的方法:
NSLog(@"Tripled: %d", [tripleNum toInt32]); // Tripled: 30
下标值
对
JSContext
和JSValue
实例使用下标的方式我们可以很容易地访问我们之前创建的context
的任何值。JSContext
需要一个字符串下标,而JSValue
允许使用字符串或整数标来得到里面的对象和数组:JSValue *names = context[@"names"]; JSValue *initialName = names[0]; NSLog(@"The first name: %@", [initialName toString]); // The first name: Grace
调用方法
JSValue
包装了一个 JavaScript 函数,我们可以从 Objective-C / Swift 代码中使用 Foundation 类型作为参数来直接调用该函数。再次,JavaScriptCore 很轻松的处理了这个桥接:JSValue *tripleFunction = context[@"triple"]; JSValue *result = [tripleFunction callWithArguments:@[@5] ]; NSLog(@"Five tripled: %d", [result toInt32]);
错误处理
JSContext
还有另外一个有用的招数:通过设置上下文的exceptionHandler
属性,你可以观察和记录语法,类型以及运行时错误。exceptionHandler
是一个接收一个JSContext
引用和异常本身的回调处理:context.exceptionHandler = ^(JSContext *context, JSValue *exception) { NSLog(@"JS Error: %@", exception); }; [context evaluateScript:@"function multiply(value1, value2) { return value1 * value2 "]; // JS Error: SyntaxError: Unexpected end of script