Reparación en caliente de iOS, solo mira aquí (te enseña cómo jugar reparación en caliente)

fondo

Debido a la incertidumbre del período de revisión de la tienda de aplicaciones, puede durar hasta 2 semanas o tan solo 1 día. Si hay algunos errores o incluso fallas fatales en la aplicación en línea, en este momento, si vuelve a publicar obedientemente una versión de acuerdo con la rutina de Apple y luego espera en silencio el ciclo de revisión aparentemente interminable, el resultado final será: un gran se perderá el número de usuarios. Por lo tanto, para algunos errores en línea, es necesario tener la capacidad de corregirlos a tiempo, que es el llamado hotfix.

A medida que las iteraciones se vuelven más frecuentes o aumenta el número de iteraciones, habrá más casos en los que la aplicación funcione de manera anormal o no esté disponible. En este momento, ¿hay alguna forma de resolver rápidamente el problema en línea? Primero, diseñe la solución de degradación al comienzo del diseño de la función, pero luego el costo de desarrollo y el costo de prueba se duplicarán, lo que significa que el usuario no puede usar la función. En este momento, la reparación en caliente es la mejor opción para resolver este tipo de problema.No solo puede solucionar el problema, sino también dejar inconsciente al usuario, que es lo mejor de ambos mundos. Tecnología de revisión de iOS Desde el webView inicial hasta el SOT reciente, el desarrollo de la tecnología es cada vez más rápido y han llegado nuevas tecnologías:

1. El primero es el principio MangoFix: (conocer el principio para trabajar mejor)

El principio básico de la reparación en caliente:

1. Interceptar la llamada del método de destino y reenviar la llamada a un método específico previamente enterrado
1. Obtener los parámetros de llamada del método de destino

Siempre que complete los dos pasos anteriores, puede hacer lo que quiera. Antes de hacer cualquier cosa, debe dominar algunas teorías básicas de Runtime.
Runtime puede crear dinámicamente clases y métodos en tiempo de ejecución, por lo que puede llamar dinámicamente a métodos OC, reemplazar dinámicamente métodos y agregar dinámicamente métodos a través de la reflexión de cadenas, etc. La siguiente es una breve introducción a los puntos de conocimiento de Runtime necesarios para la reparación en caliente.

Mecanismo de reenvío de mensajes OC

Como se puede ver en el diagrama de flujo del reenvío de mensajes en la figura anterior, el sistema nos dio 3 oportunidades de rescate.

El primer paso es agregar dinámicamente métodos no implementados a través del método class_addMethod en el método resolveInstanceMethod ;

第二步,在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

Supongo que te gusta

Origin juejin.im/post/7257333598469783610
Recomendado
Clasificación