NewLLDebugTool里面实现了一个智能monkey,现在已经支持快速遍历算法和随机遍历算法,因为monkey是集成在app里面,如果app发生crash(如果开启fuzzy功能,很容易发生crash),那么如何重新拉起app,继续运行呢?
app自己本身肯定无法拉起自己,肯定需要外力进行拉起,我自己调研有两种可行的方案:
1、通过私有api进行拉起,使用的私有api LSApplicationWorkspace
,大体代码如下所示:
+(BOOL)isOpenApp:(NSString*)appIdentifierName
{
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];
BOOL isOpenApp = [workspace performSelector:@selector(openApplicationWithBundleID:) withObject:appIdentifierName];
return isOpenApp;
}
这种方案最终我放弃了,主要考虑以下几点:1、私有api,顾名思义是苹果不允许使用的api,很可能在苹果的后续版本更新中就无法使用了,从而导致这种保活方式的可兼容性很差; 2、可扩展能力不强,如果后续我们想接入持续集成(未来的趋势),那必定需要定时或者ci的时候拉去最新的安装包跑monkey,很明显自动拉取最新包并安装到手机上,是通过私有api完成不了的,如果能完成,ios全家桶了解一下。
2、方案二也是现在我采用的方式,通过ios自带的ui自动化框架xctest进行保活。xctest里面的XCUIApplication
可以检查当前app的状态是否激活,如果未激活可以拉起app,大体代码如下所示:
public func addXCTestCheckCurrentApp(interval:Int, application:XCUIApplication) {
addCheck(interval:interval){ [weak self] in
let work = DispatchWorkItem(qos:.userInteractive){
if (application.state != XCUIApplication.State.runningForeground){
application.activate()
self?.sleep(5)
}
}
DispatchQueue.main.async(execute:work)
}
}
工程也已经开源,开源地址:MonkeyRunner,和monkey配合使用,效果更好。效果如下所示:
中间触发了一次预先写好的crash,app闪退,但是被xctest重新拉起,monkey继续运行,如果我们想要停止monkey,只需要摇一摇手机停止monkey即可。
如果大家觉得这个项目还可以的话,点上一颗star吧。
参考文章
1、https://www.cnblogs.com/eagle927183/p/shakeandcutter.html
2、https://www.v2ex.com/t/293850
3、https://www.cnblogs.com/qingjoin/p/5443656.html