美文网首页
利用JavaScriptCore自定义计算器

利用JavaScriptCore自定义计算器

作者: LonnieQ | 来源:发表于2020-10-05 23:36 被阅读0次

    在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
    

    相关文章

      网友评论

          本文标题:利用JavaScriptCore自定义计算器

          本文链接:https://www.haomeiwen.com/subject/uzyzuktx.html