在JavaScriptCore中,我们可以给JSContext实例通过下标函数注册函数和变量。然后我们可以利用js代码调用注册的函数和变量来进行计算。代码如下:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h"
@import JavaScriptCore;
@interface ViewController ()
@property (nonatomic, retain) UILabel * label;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.label = [UILabel new];
[self.view addSubview:self.label];
self.label.numberOfLines = 0;
self.label.font = [UIFont preferredFontForTextStyle: UIFontTextStyleBody];
self.label.translatesAutoresizingMaskIntoConstraints = false;
[self.view addConstraints: @[
[self.label.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor constant:16],
[self.label.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor constant:16],
[self.label.topAnchor constraintEqualToAnchor: self.view.topAnchor constant:16],
[self.label.bottomAnchor constraintEqualToAnchor: self.view.bottomAnchor constant:16],
]];
JSContext * context = [[JSContext alloc] init];
context[@"sin"] = ^(double a) {
return sin(a);
};
context[@"cos"] = ^(double a) {
return cos(a);
};
context[@"tan"] = ^(double a) {
return tan(a);
};
context[@"asin"] = ^(double a) {
return asin(a);
};
context[@"acos"] = ^(double a) {
return acos(a);
};
context[@"atan"] = ^(double a) {
return atan(a);
};
context[@"sinh"] = ^(double a) {
return sinh(a);
};
context[@"cosh"] = ^(double a) {
return cosh(a);
};
context[@"tanh"] = ^(double a) {
return tanh(a);
};
context[@"asinh"] = ^(double a) {
return asinh(a);
};
context[@"acosh"] = ^(double a) {
return acosh(a);
};
context[@"atanh"] = ^(double a) {
return atanh(a);
};
context[@"pow"] = ^(double a, double b) {
return pow(a, b);
};
context[@"sqrt"] = ^(double a) {
return sqrt(a);
};
context[@"hypot"] = ^(double a, double b){
return hypot(a, b);
};
context[@"pi"] = [JSValue valueWithDouble:M_PI inContext: context];
context[@"e"] = [JSValue valueWithDouble:M_E inContext: context];
NSArray<NSString*> * expressions = @[@"e", @"pi", @"sin(pi/3)", @"cos(pi/3)", @"tan(pi/3)", @"asin(1)", @"acos(1)", @"atan(1)", @"sinh(pi/3)", @"cosh(pi/3)", @"tanh(pi/3)", @"asinh(0.5)", @"acosh(1.1)", @"atanh(0.5)", @"pow(100, 2)", @"sqrt(33)", @"hypot(3, 4)"];
NSMutableString * string = [NSMutableString new];
[expressions enumerateObjectsUsingBlock:^(NSString * _Nonnull script, NSUInteger idx, BOOL * _Nonnull stop) {
[string appendFormat:@"%@=%@\n", script, [context evaluateScript: script]];
}];
self.label.text = string;
}
显示结果如下:
截屏2020-10-05 23.37.15.png
以上仅仅适用于Objective-C, 如果是Swift语言, 我们需要先定义一个继承自JSExport
协议的协议,在这个协议定义接口暴露给JavaScriptCore
, 这些接口的输入参数和输出参数需要是Swift基本数据类型。注册的对象需要实现这样的协议。以下是一个简单的例子:
import JavaScriptCore
@objc protocol MathProtocol: JSExport {
func add(_ lhs: Double, _ rhs: Double) -> Double
func minus(_ lhs: Double, _ rhs: Double) -> Double
func multiply(_ lhs: Double, _ rhs: Double) -> Double
func divide(_ lhs: Double, _ rhs: Double) -> Double
}
class Math: NSObject, MathProtocol {
func add(_ lhs: Double, _ rhs: Double) -> Double {
return lhs + rhs
}
func minus(_ lhs: Double, _ rhs: Double) -> Double {
return lhs - rhs
}
func multiply(_ lhs: Double, _ rhs: Double) -> Double {
return lhs * rhs
}
func divide(_ lhs: Double, _ rhs: Double) -> Double {
return lhs / rhs
}
}
let context = JSContext()!
context.setObject(JSValue(double: 25, in: context), forKeyedSubscript: "a" as NSString)
context.setObject(JSValue(double: 5, in: context), forKeyedSubscript: "b" as NSString)
context.setObject(Math(), forKeyedSubscript: "math" as NSString)
print(context.evaluateScript("math.add(a, b)")!.toString()!) // 30
print(context.evaluateScript("math.minus(a, b)")!.toString()!) // 20
print(context.evaluateScript("math.multiply(a, b)")!.toString()!) // 125
print(context.evaluateScript("math.divide(a, b)")!.toString()!) // 5
网友评论