一字一字的,踩过很多坑。我在本文会顺带说一下踩过得坑,以防其他人再踩,哈哈。
对于iOS应用来说,通过官方渠道AppStore进行应用程序的发布要通过人工审核,有时这个审核周期会非常长,如果在开发者在编写代码时留下了一些小漏洞,应用一旦上线,若要修改掉这个bug就十分艰难了。有了JSPatch,我们可以想象,如果可以定位到线上应用有问题的方法,就可以使用JS文件来修改掉这个方法。事实上,JSPatch的主要用途也是可以实现线上应用极小问题的热更新。
JSPatch的配置这里就不说明了,官方文档都有。
Objective-c转JavaScript的细节如下:
1:引用类
OC:import “XXX.h”
JS:require('XXX’),当然也可以直接在使用的时候引用,require('UIView').alloc().init(),但是不方便查看,建议还是先引用再使用。
2:方法调用
(1):类方法调用:通过类名打点的方式来调用类方法,格式类似如下,括号内为参数传递:
JS:UIColor.redColor()
(2):实例方法调用:通过对象打点的方式调用类的实例方法,格式如下,括号内为参数传递:
JS:view.addSubview(label)
(3):对于多参数的方法调用:转化为JavaScript将参数分割的位置以_进行分割,参数全部放入后面的括号中,以逗号分割,示例如下:
JS:view.setBackgroundColor(UIColor.colorWithRed_green_blue_alpha(0,0.5,0.5,1))、
注意:如果原Objective-C的方法中已经包含了_符号,则在JavaScript中使用__代替。我就在这个地方踩过大坑!!!切记切记。
注意:如果你打印对象的时候出现这个问题[object Object],说明你的对象需要序列化,本人也在这个地方踩过坑
OC代码转JS代码:
1:Method declaration
OC:- (void)requestUrl:(NSString *)url param:(NSDictionary *)dict {}
JS:requestUrl_param: function(url, dict) {}
2:Method calling
OC:[[JPRequest alloc] initWithUrl:url param:dict];
JS:JPRequest.alloc().initWithUrl_param(url, dict);
3:Block syntax
OC:[JPRquest handleCallback:^(id data, NSError *err) {}];
JS:JPRquest.handleCallback(block('id,NSError*', function(data, err) {}));
4:Variable declaration
OC:NSString *str = @"content";
JS:var str = "content";
5:Getting/Setting Property
OC:
self.handler.successBlock(data);
self.handler.data = [[JPData alloc] init];
JS:
self.handler().successBlock()(data);
self.handler().setData(JPData.alloc().init());
6:NSString / NSArray / nil ...
OC:NSDictionary *dict = nil;
dict = @{ @"arr": @[@(1), @"2"]};
JS:var dict = null;
dict = { "arr": [(1), "2"]};
下面举例子说明:我会写上OC的代码,然后对应的JS代码,方便对照:
例子1:
OC:
- (NSString *)showShopName{
NSString *text=@"";
if ([s.hour_tab_enable isEqualToString:@"1"]&& [s.tuan_tab_enable isEqualToString:@"0"]) {
text=s.AllShopName;
s.currentIndex=0;
}else if ([s.hour_tab_enable isEqualToString:@"0"]&& [s.tuan_tab_enable isEqualToString:@"1"]) {
text=s.regionName;
s.currentIndex=1;
}else if ([s.hour_tab_enable isEqualToString:@"1"]&& [s.tuan_tab_enable isEqualToString:@"1"]) {
if (s.currentIndex == 0) {
text=s.AllShopName;
}else{
text=s.regionName;
}
}else if ([s.hour_tab_enable isEqualToString:@"0"]&& [s.tuan_tab_enable isEqualToString:@"0"]){
text=@"暂无站点";
s.currentIndex=1;
}
return text;
}
JS:
也许你上网上搜JS的字符串比较的方法,出来一堆说是让你用 == 或者 === 的,千万不要用。因为不符合OC的规则。如果是打补丁包要用比较字符串的话,要用 xxx.isEqualToString("yyy"):xxx与yyy是一样的。
require('PersonalSetting');
defineClass('MainViewController', {
showShopName: function() {
var text = "test";
var ss = PersonalSetting.getInstance();
var hour = ss.hour__tab__enable();
var tuan = ss.tuan__tab__enable();
if (hour.isEqualToString("1") && tuan.isEqualToString("0")) {
text = ss.AllShopName();
ss.setCurrentIndex(0);
} else if ( hour.isEqualToString("0") && tuan.isEqualToString("1")) {
text = ss.regionName();
ss.setCurrentIndex(1);
} else if (hour.isEqualToString("1") && tuan.isEqualToString("1")) {
if (ss.currentIndex() == 0) {
text = ss.AllShopName();
} else {
text = ss.regionName();
}
} else if (hour.isEqualToString("0") && tuan.isEqualToString("0")) {
text = "暂无站点";
ss.setCurrentIndex(1);
}
return text;
},
});
2:
多参数函数的转换
OC
- (void)setRootViewController:(UINavigationController *)viewController
withTransition:(UIViewAnimationOptions)transition
completion:(void (^)(BOOL finished))completion{
UIWindow *window=[[UIApplication sharedApplication].delegate window];
UIViewController *oldViewController = window.rootViewController;
window.backgroundColor=f6f6f6Color;
[UIView transitionFromView:oldViewController.view
toView:viewController.view
duration:0.7f
options:(UIViewAnimationOptions)(transition|UIViewAnimationOptionAllowAnimatedContent|UIViewAnimationOptionLayoutSubviews)
completion:^(BOOL finished) {
window.rootViewController = viewController;
completion(YES);
}];
}
JS:
defineClass('UZGGuiderViewController',{
setRootViewController_withTransition_completion:function (viewController,transition,completion) {
var window = UIApplication.sharedApplication().delegate().window();
var oldViewController = window.rootViewController();
var oldView = oldViewController.view();
var newView = viewController.view();
window.setBackgroundColor(UIColor.colorFromHexCode("#f6f6f6"));
UIView.transitionFromView_toView_duration_options_completion(oldView,newView,0.7,(5<<20|1<<7|1<<0),block('BOOL'),function(finished) {
window.setRootViewController(viewController);
completion(1);
})
}
});
var contentOffset = self.scrollView().contentOffset().x;( x后面不要跟() )
因为用JSPatch方法,必须要重写项目的整个方法,所以,你的项目中的方法函数,一定不能过长,不然打补丁包的时候很麻烦的,波及范围太广。。。