ios如何进行启动崩溃保护

ios如何进行启动崩溃保护_第1张图片

网传上个月下旬小红书因为配置问题导致连续性启动崩溃,最终只能通过紧急发版解决。对于冷启动崩溃保护的最容易查到的资料来源于微信读书团队的分享。
何为保护?要保护什么?该怎样保护?带着这几个疑问,一一谈一下个人的见解。

何为保护

所谓保护只不过是检测到出现连续性启动崩溃的补救措施,而不是防范于未然。
这里涉及到三个问题,针对这三个问题分别谈一下个人看法:

  1. 如何定义启动崩溃
    一般是用户点击桌面图标触发App冷启动,在启动活动的某个标志时间点或事件节点内出现的崩溃,我们称之为启动崩溃。
    这里又涉及到一个标志时间或事件的问题,一般考虑的条件是常规且必要的任务执行完毕,如热修复脚本检查更新完毕,离线配置更新完毕,必要的SDK和业务初始化完毕。针对不同App这个时间可能很短也可能较长,我们至少要保证常规的线上问题修复手段能奏效(如加载热修脚本),即保证常规的问题修复手段先行。只有常规手段不能有效防止问题出现时才应走到不得已而为之的启动保护。

  2. 如何定义连续
    假如第一个问题得到的时间或事件节点是A,则在A发生前出现的崩溃都属于启动崩溃,所谓连续性即不间断出现在A发生之前的崩溃现象。

  3. 怎样进行崩溃计数
    两种方案:
    第一种:常见的崩溃统计如bugly、KSCrash、PLCrash都有外漏的处理崩溃事件接口,只需要在响应的接口里进行计数即可。
    第二种:通过代码监听Unix、Mach和UncaughtException,具体可以参考KSCrash的实现,需要注意的点是在处理异常时尽量不要做繁重的事物,处理完毕要转发异常,以免影响crash收集工具工作。

要保护什么

为何出现连续崩溃,小红书的例子是老配置引起崩溃,但App启动后在新配置拉下来之前就出现了崩溃,也就是说如果正确的新配置能拉下来就可以避免后续再出现相同的崩溃。
所谓保护,即通过一种手段保证持续性的崩溃能最大限度的被修复。

该怎样保护

这个问题的前提是出现了技术手段无法形成有效影响的连续性crash问题。因此保护的措施就是在出现连续启动crash时挂起正常的启动流程,临时进入一种特殊的保护状态,在此状态下进行一些预定义的必要操作,以求能最大限度的修复/规避crash达到快速止损的目的。

  1. 出现几次进入保护状态
    业内一般连续3次及以上,原因大概是两次或更少可能出现临时异常导致误触,太多用户可能会放弃尝试。

  2. 如何实现保护状态
    两种方式:
    第一种:通过runtime方法交换hookdidFinishLaunchingdidBecomeActive两个必要的生命周期方法,hook后。原函数是正常启动流程,新函数就承担了是否进入保护流程以及实现保护操作的责任。
    因此可以根据连续crash数决定是否调用原函数。
    为了保证用户视觉上处于正常状态,保护流程中可以设置window的rootViewController,在该Controller中可以用户做一些提示性信息。当然具体的保护策略也可以在这个Controller中实现。

  3. 保护操作完成后该如何
    保护策略完成后App应该走正常的启动流程,因为冷启过程会走两个生命周期方法,因此分别调用这两个方法即可。

应该怎样制定保护策略呢?
一个问题出现的原因总体上可以分为外部原因和内部原因两类,出现连续性crash,尤其是大规模连续性crash的内部原因(即App自身的原因)通常是代码健壮性不够,对异常数据或数据类型的兼容度有缺失。
外部原因通常是来自外部的数据有问题,导致在解析或使用过程中出现崩溃。而来自外部的数据大多是API接口数据,API接口可能来自自己内部的服务,也可能来自三方服务,甚至是三方crash sdk本身。极端情况下,内部API接口可以随时调整和上线,但对三方服务的接口却无能为力,因此开发App时应该注重对数据的合法性及安全性校验。

保护策略,一般涉及以下内容:

  1. 拉取热修复脚本(修复/规避某些代码异常)
  2. 删除API数据的缓存(针对离线数据引起的crash)
  3. 删除非必要的数据库(针对数据库导致的crash)
  4. 拉取一些预定义操作的配置(如配置是否初始化某个sdk、移除特定路径下的内容等)

最近重构冷启动保护策略,写了个简单的任务管理框架来实现异常监听和启动任务托管,代码见GitHub

你可能感兴趣的:(ios,objective-c)