iOS hot repair, just look here (teach you how to play hot repair)

background

For the uncertainty of app store review period, it can be as long as 2 weeks or as short as 1 day. If there are some bugs or even fatal crashes in the online application, at this time, if you obediently re-release a version according to Apple's routine, and then quietly wait for the seemingly endless review cycle, the final result will be: a large number of users will be lost. Therefore, for some online bugs, it is necessary to have the ability to fix them in time, which is the so-called hotfix.

As the iterations become more frequent or the number of iterations increases, there will be more cases where the application functions abnormally or becomes unavailable. At this time, is there any way to quickly solve the online problem? First, design the downgrading solution at the beginning of function design, but then the development cost and testing cost will double; , which means the user cannot use the feature. At this time, hot repair is the best choice to solve this kind of problem. It can not only fix the problem, but also make the user unconscious, which is the best of both worlds. iOS hot fix technology From the initial webView to the recent SOT, the development of technology is getting faster and faster, and new technologies have arrived:

1. The first is the principle MangoFix: (know the principle to work better)

The core principle of hot repair:

1. Intercept the target method call and forward the call to a pre-buried specific method
1. Get the call parameters of the target method

As long as you complete the above two steps, you can do whatever you want. Before doing anything, you need to master some basic theories of Runtime.
Runtime can dynamically create classes and methods at runtime, so you can dynamically call OC methods, dynamically replace methods, and dynamically add methods through string reflection. method and so on. The following is a brief introduction to the Runtime knowledge points needed for hot repair.

OC message forwarding mechanism

As can be seen from the flow chart of message forwarding in the above figure, the system gave us 3 chances to rescue.

The first step is to dynamically add unimplemented methods through the class_addMethod method in the resolveInstanceMethod method ;

第二步,在forwardingTargetForSelector方法里返回备用的接受者,通过备用接受者里的实现方法来完成调用;

第三步,系统会将方法信息打包进行最终的处理,在methodSignatureForSelector方法里可以对自己实现的方法进行方法签名,通过获取的方法签名来创建转发的NSInvocation对象,然后再到forwardInvocation方法里进行转发。

方法替换就利用第三步的转发进行替换。

当然现在有现成的,初级及以上iOS开发工程师很快就可以理解的语法分析,大概了解一下mangofix是可以转化oc和swift代码的:具体详情请看
www.jianshu.com/p/7ae91a2da…

那么为什么它可以执行转化呢,转化逻辑是什么?
MangoFix项目主页上中已经讲到,MangoFix既是一个iOS热修复SDK,但同时也是一门DSL(领域专用语言),即iOS热修复领域专用语言。既然是一门语言,那肯定要有相应的编译器或者解析器。相对于编译器,使用解析器实现语言的执行,虽然效率低了点,但显然更加简单和灵活,所以MangoFix选择了后者。下面我们先用一张简单流程图,看一下MangoFix的运行原理,然后逐一解释。

image.png

1、MangoFix脚本

首先热修复之前,我们先要准备好热修复脚本文件,以确定我们的修复目标和执行逻辑,这个热修复脚本文件便是我们这里要介绍的MangoFix脚本,正常是放在我们的服务端,然后由App在启动时或者适当的运行期间进行下载,利用MangoFix提供的MFContext对象进行解析执行。对于MangoFix脚本的语法规则,这点可以参考MangoFix Quick Start,和OC的语法非常类似,你如果有OC开发经验,相信你花10分钟便可以学会。当然,在后续的文章中我可能也会介绍这一块。

2、词法分析器

几乎所有的语言都有词法分析器,主要是将我们的输入文件内容分割成一个个token,MangoFix也不例外,MangoFix词法分析器使用Lex所编写,如果你想了解MangoFix词法分析器的代码,可以点击这里

3、语法分析器

和词法分析器类似,几乎所有语言也都有自己的语法分析器,其主要目的是将词法分析器输出的一个个token构建成一棵抽象语法树,而且这颗抽象语法树是符合我们预先设计好的上下文无关文法规则的,如果你想了解MangoFix语法分析器的代码,可以点击这里

4、语义检查

由于语法分析器输出的抽象语法树,只是符合上下文无关文法规则,没有上下文语义关联,所以MangoFix还会进一步做语义检查。比如我们看下面代码:

less  
复制代码  
@interface MyViewController : UIViewController  
  
@end  
angelscript  
复制代码  
class MyViewController : BaseViewController{  
  
- (void)viewDidLoad{  
    //TODO  
}  
  
}  

上面部分是OC代码,下面部分是MangoFix代码,从文法角度MangoFix这个代码是没有问题的,但是在逻辑上却有问题, MyViewController在原来OC中和MangoFix中继承的父类不一致,这是OC runtime所不允许的。

5、创建内置对象

MangoFix脚本中很多功能都是通过预先创建内置对象的方式支持的,比如常用结构体的声明、变量、宏、C函数和GCD相关的操作等,如果想详细了解MangoFix中有哪些内置对象,可以点击这里。当然MangoFix也开放了相关接口,你也可以向MangoFix执行上下文中注入你需要的对象。

6、执行顶层语句

在做完上面的操作后,MangoFix解析器就开 始真正执行MangoFix脚本了,比如顶层语句的执行、结构体的声明、类的定义等。

7、利用runtime热修复

现在就到了最关键一步了,就是利用runtime替换掉原来Method的IMP指针,MangoFix利用libffi库动态创建C函数,在创建的C函数中调用MangoFix脚本中方法,然后用刚刚创建的C函数替换原来Method的IMP指针,当然MangoFix也会保留原有的IMP指针,只不过这时候该IMP指针对应的selector要在原有的基础上在前面拼接上ORG,这一点和JSPatch一致。当然,MangoFix也支持对属性的添加。

8、MangoFix方法执行

最后当被修复的OC方法在被调用的时候,程序会走到我们动态创建的C函数中,在该函数中我们通过查找一个全局的方法替换表,找到对应的MangoFix方法实现,然后利用MangoFix解析器执行该MangoFix的方法。

二. 具体执行(OC修复OC)。

1.后台分发补丁平台:

补丁平台:patchhub.top/mangofix/lo…

github地址:github.com/yanshuimu/M…

  1. 首先你要明白:必须得有个后台去上传,分发bug的文件,安全起见,脚本已经通过AES128加密,终端收到加密的脚本再去解密,防止被劫持和篡改,造成代码出现问题。
    登录这个补丁平台,可以快速创建appid。
    github地址下载并配合使用:
    以下是MangoFixUtil的说明:
    MangoFixUtil是对MangoFix进行了简单的封装,该库在OC项目中实战已经近2年多,经过多次迭代,比较成熟。但需要搭配补丁管理后台一起使用,后台由作者开发维护,目前有50+个已上架AppStore的应用在使用,欢迎小伙伴们使用。

  2. 举个实战中的例子:

我们快速迭代中遇到的一些问题:
image.png

有一次我们解析到后台数据从中间截取字符串,然而忘了做判空操作,后台数据一旦不给返回,那么项目立马崩溃,所以做了热修复demo.mg文件放到Patch管理平台,具体代码如OC基本一致:

class JRMineLoginHeaderView:JRTableViewHeaderView {  
  
- (NSString *)getNetStringNnm:(NSString *)str{  
    NSError *error = nil;  
    if(str.length<=0) {  
        return @"";  
    }  
      
    NSRegularExpression *regex = NSRegularExpression.regularExpressionWithPattern:options:error:(@"\d+",0,&error);  
  
    if (error) {  
        return @"";  
    } else {  
      
    if (str.length == 0) {  
        return @"";  
    }  
          
        NSArray *matches = regex.matchesInString:options:range:(str,0,NSMakeRange(0, str.length));  
        for (NSTextCheckingResult *match in matches) {  
            NSString *matchString = str.substringWithRange:(match.range);  
            return matchString;  
        }  
    }  
    return @"";  
}  
  
}  

以上代码中,新增了对象长度判空操作:  if(str.length<=0) {
return @"";
}
完美的解决了崩溃的问题。

2.oc转换成DSL语言。

一切准备就绪,oc转换成DSL语言浪费人力,而且准确率又低怎么办?怎么可以快速的用oc转换成mangofix语言呢?
这是macOS系统上的可视化辅助工具,将OC语言转成mangofix脚本。

做iOS热修复时,大量时间浪费在OC代码翻译成脚本上,提供这个辅助工具,希望能给iOSer提供便利, 本人写了一个mac应用,完美的解决了不同语法障碍,转换问题。
mac版本最低(macos10.11)支持内容:

(1)OC代码 一键 批量转换成脚本

(2)支持复制.m内容粘贴,转换

(3)支持单个OC API转换,自动补全

(4)报错提示:根据行号定位到OC代码行

自动转化文件QQ群获取。

3.打不开“OC2PatchTool.app”,因为它来自身份不明的开发者

方案1.系统偏好设置>>安全与隐私>>允许安装未知来源

方案2.打开 Terminal 终端后 ,在命令提示后输入

sudo spctl --master-disable  

OC 转换成 脚本 支持两种方式

方式1.拷贝.m文件所有内容,粘贴到OC输入框内。 示例代码:AFHTTPSessionManager.m  

image.png

方式2. 拷贝某个方法粘贴到OC输入框内,转换时会自动补全  

image.png

三.App 审核分析

其实能不能成功上线是热修复的首要前提,我们辛辛苦苦开的框架如果上不了线,那一切都是徒劳无功。下面就来分析下其审核风险。

-   首先这个是通过大量C语言混编转换的,所以苹果审核无法通过静态代码识别,这一点是没有问题的。
-   其次系统库内部也大量使用了消息转发机制。这一点可以通过符号断点验证_objc_msgForwardforwardInvocation:。所以不存在风险。此外,你还可以通过一些字符串拼接和base64编码方式进行混淆,这样就更加安全了。
-   除非苹果采用动态检验消息转发,非系统调用都不能使用,但这个成本太大了,几乎不可能。
-   Mangofix 库目前线上有大量使用,为此不用担心。就算 Mangofix 被禁用,参考 Mangofix 自己开发也不难。

综上所述:超低审核风险。

热修复框架只是为了更好的控制线上bug影响范围和给用户更好的体验。
建议:
Hotfix会在应用程序运行时动态地加载代码,因此需要进行充分的测试,以确保修复的bug或添加的新功能不会导致应用程序崩溃或出现其他问题。

有兴趣的一起来研究,QQ群:770600683

Guess you like

Origin juejin.im/post/7257333598469783610