JSPatch 做到了让JS调用/替换任意OC方法,让iOS APP具备hotfix的能力
1.引入执行js脚本
[JPEngine startEngine];
直接执行JS脚本
[JPEngineevaluateScript:@"\
console.log(‘call JPEngine success‘);\
"];
执行本地JS文件demo.js脚本
NSString *sourcePath = [[NSBundlemainBundle] pathForResource:@"demo"ofType:@"js"];
NSString *script = [NSStringstringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncodingerror:nil];
[JPEngineevaluateScript:script];
2.基本语法
2.1 调用objc方法
//objc方法
UIView *view = [[UIView alloc] init];
//js方法
var view = require(‘UIView‘).alloc().init();
//require(‘UIView‘)会在JS全局作用域上创建一个同名变量,变量指向一个对象,之后调用可直接如下
var view = UIView.alloc().init();
调用含参方法
//objc方法
[view setBackgroundColor:[UIColor redColor]];
//js方法
view.setBackgroundColor(UIColor.redColor());
调用多参数方法
//objc方法
[UIView beginAnimations:nil context:nil];
//js方法
UIView.beginAnimations_context(null, null);//多参数中间用"_"连接
给原方法添加新的代码
//objc
@implementation CustomViewController
- (void) viewDidLoad {
[super viewDidLoad];
}
@end
// js
defineClass("CustomViewController", {
viewDidLoad: function() {
self.ORIGviewDidLoad();
self.view().setBackgroundColor(require(‘UIColor‘).whiteColor());
},
})
2.2 objc属性
//objc方法
UIColor *color = view.backgroundColor;
view.backgroundColor = [UIColor redColor];
//js方法
var color = view.backgroundColor();
view.setBackgroundColor(UIColor.redColor());
//创建属性
//objc方法
@property(nonatomic, strong)NSArray *data;
//js方法
data: function() {
var data = self.get_prop(‘data‘);
if(data) return data;
var data = [];
for(var i=0; i < 20; i++){
data.push("js data "+ i);
}
return data;
}
//属性已下划线开始
//objc
self.set_unserLineString(‘test test test‘);
//js
self.set__underLineString(‘test test test‘);//双下划线
2.3实例变量
//objc方法
@interface CustomObject()
NSString *_string;
@end
_string = @"string";
//js方法
get:
var string = self.valueForKey(‘_string‘);
set:
self.setValue_forKey(‘string‘, ‘_string‘);
2.4字符串、数组、字典
//objc方法
NSString *string = [NSString stringWithString:@"string"];
NSArray *array = [[NSArray alloc] initWithArray:@[@"string0", @"string1", @"string2"]];
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:@{@"key0":@"value0", @"key1":@"value1",@"key2":@"value2"};
//js方法
var string = ‘string‘;
var array = [‘string0‘, ‘string1‘, ‘string2‘];
var dict = {‘key1‘:‘value1‘,‘key1‘:‘value1‘};
console.log(require(‘NSString‘).stringWithString(string).toJS());//调用toJS()方法将对应方法转化为对应的JS类型
console.log(require(‘NSArray‘).alloc().initWithArray(data).objectAtIndex(0).toJS());
console.log(require(‘NSDictionary‘).alloc().initWithDictionary(dict).objectForKey(‘key1‘).toJS());
2.5Block
//objc方法
@property(nonatomic, copy) NSNumber * (^ addBlock)(NSInteger, NSInteger);
//setter
self.addBlock = ^(NSInteger a, NSInteger b){[email protected](a + b);};
//getter
self.addBlock(1,2);
//js方法
//setter
self.setAddBlock(block("NSInteger, NSInteger", function(a, b){
//getter
var blk = self.addBlock();
blk(1,2);
return a + b;//使用block时,js返回值为NSObject类型,这里返回NSNumber类型
}));
//从JS传block到OC,有两个限制:A. block 参数个数最多支持4个。(若需要支持更多,可以修改源码)B. block 参数类型不能是 double。
//防止循环引用,使用__weak和__strong
var weakSelf = __weak(self);
self.setCustomBlock(block(function(){
var strongSelf = __strong(weakSelf);
strongSelf.customMethod();
}));
2.6GCD
//objc方法
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
});
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
//js方法
dispatch_async_global_queue(function(){
dispatch_async_main(function(){
});
});
dispatch_after(1.0, function(){
});