Notes

JavaScriptCore

配套一个例子:JavaScriptCoreBox

JavaScriptCore 主要的类及之间的关系

JavaScriptCore 中主要的类有

JSVirtualMachine, JSContext, JSValue 三者的关系

Native 调用 JavaScript 代码

  1. 创建 JSContext 实例
  2. 运行 [context evaluateScript:jscode] 来直接运行 JavaScript 代码或注册 JavaScript 代码
  3. 若在 2 中注册了 JavaScript 代码,如,注册了一个方法 foo, 则可以通过

     JSValue *fooFunction = [self.context objectForKeyedSubscript:@"foo"];
     // 或者,两种方法的效果一样,但在 Swift 中只可以使用 👆
     JSValue *fooFunction = self.context[@"foo"];
    

    来获取到 foo 方法,从 JavaScript 返回来的值都是 JSValue 类型

  4. 获取到 JavaScript 方法后,可以直接调用

     NSArray *result = [[fooFunction callWithArguments:@[@(TheArgument)]] toArray];
    
    • callWithArguments 中,如果没有参数传递,则直接传 nil
    • 由于 JavaScript 返回来的数据都是 JSValue 类型,要转为 Native 对象,则需要调用类似 toArray 的方法来进行转换

JavaScript 调用 Native 代码

JavaScript 方法注册,Native 调用

// 注册
self.context[@"outterLog"] = ^(NSString *logMsg) {
    return [NSString stringWithFormat:@"outterLog: %@", logMsg];
};

// 调用
NSString *result = [[self.context evaluateScript:@"outterLog('hey, log from outter')"] toString];
self.tvReturnValue.text = [NSString stringWithFormat:@"innerLog: %@", result];

// 注册
// 注意  retain cycle
__weak typeof(self) weakSelf = self;
self.context[@"innerLog"] = ^(NSString *logMsg) {
    dispatch_async(dispatch_get_main_queue(), ^{
        weakSelf.tvWithoutReturnValue.text = [NSString stringWithFormat:@"innerLog: %@", logMsg];
    });
};

// 调用
[self.context evaluateScript:@"innerLog('hey, log from inner')"];

使用 JSExport 协议

  1. 自定义一个协议,继承于 JSExport 协议,如

     @protocol HumanJSable<JSExport>
        
     @property (nonatomic, copy) NSString *name;
     - (NSString *)nameIt;
        
     @end
    
  2. 新建 Native 类,该类实现自定义的协议
  3. 新建 Native 对象,并将对象以键值方式赋值,传递到 JSContext
  4. 通过 JavaScript 代码直接调用

     Human *human = [[Human alloc] initWithName:@"Alice" age:20];
     self.context[@"human"] = human;
            
     NSString *name = [[self.context evaluateScript:@"human.nameIt()"] toString];
     self.tvResult.text = name;
    

Objective-C 对象导出到 JavaScript

Objective-C 方法属性暴露到 JavaScript

References