iOS中使用JSPatch框架使Objective-C与JavaScript代码交互

2020-01-15 15:53:45王振洲

JSPatch是GitHub上一个开源的框架,其可以通过Objective-C的run-time机制动态的使用JavaScript调用与替换项目中的Objective-C属性与方法。其框架小巧,代码简洁,并且通过系统的JavaScriptCore框架与Objective-C进行交互,这使其在安全性和审核风险上都有很强的优势。Git源码地址:https://www.easck.com/pre>

在工程中添加一个js文件,编写如下:

  


 require('UIView, UIColor, UILabel')
  //要替换函数的类
  defineClass('AppDelegate', {
      //替换函数
        //要替换函数的名称
        genView: function() {
          var view = self.ORIGgenView();
          view.setBackgroundColor(UIColor.greenColor())
          var label = UILabel.alloc().initWithFrame(view.frame());
          label.setText("JSPatch");
          label.setTextAlignment(1);
          view.addSubview(label);
          return view;
      }
  });

运行工程,可以看到genView方法被替换成了js文件中的方法,原本红色的视图被修改成了绿色。

二、使用JavaScript代码向Objective-C中修改或添加方法

JSPatch引擎中支持3中方式进行JavaScript代码的调用,分别是使用JavaScript字符串进行代码运行,读取本地的JavaScript文件进行代码运行和获取网络的JavaScript文件进行代码运行。例如,如果想要通过JavaScript代码在项目中弹出一个警告框,在Objective-C代码中插入如下代码:


- (void)viewDidLoad {
  [super viewDidLoad];
  // ‘'符用于进行换行
  [JPEngine evaluateScript:@"
   var alertView = require('UIAlertView').alloc().init();
   alertView.setTitle('Alert');
   alertView.setMessage('AlertView from js'); 
   alertView.addButtonWithTitle('OK');
   alertView.show(); 
   "];
}

开发者也可以动态在Objective-C类文件中添加方法,例如在ViewController类中编写如下:


- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor whiteColor];
  [JPEngine startEngine];
  NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"];
  NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil];
  [JPEngine evaluateScript:script];
  [self performSelectorOnMainThread:@selector(creatView) withObject:nil waitUntilDone:nil];
}

JavaScript文件代码如下:


 require('UIView, UIColor, UILabel')
  defineClass('ViewController', {
      // replace the -genView method
        creatView: function() {
          var view = UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100});
          view.setBackgroundColor(UIColor.greenColor());
          var label = UILabel.alloc().initWithFrame({x:0, y:0, width:100, height:100});
          label.setText("JSPatch");
          label.setTextAlignment(1);
          view.addSubview(label);
        self.view().addSubview(view)
      }
  });