iOS JSPatch打补丁包

一字一字的,踩过很多坑。我在本文会顺带说一下踩过得坑,以防其他人再踩,哈哈。

对于iOS应用来说,通过官方渠道AppStore进行应用程序的发布要通过人工审核,有时这个审核周期会非常长,如果在开发者在编写代码时留下了一些小漏洞,应用一旦上线,若要修改掉这个bug就十分艰难了。有了JSPatch,我们可以想象,如果可以定位到线上应用有问题的方法,就可以使用JS文件来修改掉这个方法。事实上,JSPatch的主要用途也是可以实现线上应用极小问题的热更新。

JSPatch的配置这里就不说明了,官方文档都有。


Objective-c转JavaScript的细节如下:


1:引用类

    OC:import “XXX.h

     JSrequire('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代码:

1Method declaration

  OC- (void)requestUrl:(NSString *)url param:(NSDictionary *)dict {}

  JSrequestUrl_param: function(url, dict) {}


2Method calling

   OC[[JPRequest alloc] initWithUrl:url param:dict];

   JSJPRequest.alloc().initWithUrl_param(url, dict);


3Block syntax

   OC[JPRquest handleCallback:^(id data, NSError *err) {}];

    JSJPRquest.handleCallback(block('id,NSError*', function(data, err) {}));


4Variable declaration

   OCNSString *str = @"content";

    JSvar str = "content";


5Getting/Setting Property

   OC

         self.handler.successBlock(data);

         self.handler.data = [[JPData alloc] init];

   JS

         self.handler().successBlock()(data);

         self.handler().setData(JPData.alloc().init());


6NSString / NSArray / nil ...

    OCNSDictionary *dict = nil;

            dict = @{ @"arr": @[@(1), @"2"]};

    JSvar 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方法,必须要重写项目的整个方法,所以,你的项目中的方法函数,一定不能过长,不然打补丁包的时候很麻烦的,波及范围太广。。。

我们学习JS是为了在遇到问题的时候能及时修复代码,以免影响用户体验,但是能不打补丁尽量不要打补丁。毕竟会耗性能的,呼呼。今天更新到这里,后续继续再更。主要是写小例子。

你可能感兴趣的:(iOS开发,JSPatch)