嗯,我找不到任何关于从自动化脚本监控日志的信息,所以我用另一种方式解决了这个问题,目前看来效果很好。
基本思想是使用 UI 元素代替使用日志作为信号。我在我的应用程序委托中创建了一个简单的方法,它在屏幕外创建一个空标签并为其分配一个已知的accessibilityIdentifier(dispatch_after 不是绝对必要的,但我想确保控制在捕获之前返回到主事件循环)。
- (void)signalScreenshot:(int)number {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if ( ![[[NSProcessInfo processInfo] arguments] containsObject:@"automatedexecution"] ) {
NSLog(@"Screenshot signaled, but ignoring because we are not in automated execution.");
return;
}
UILabel* elem = [[UILabel alloc] initWithFrame:CGRectMake(-100, -100, 50, 50)];
elem.accessibilityIdentifier = [NSString stringWithFormat:@"screenshotSignal_%d", number];
NSLog(@"Signaling for screenshot %d...", number);
[self.window insertSubview:elem atIndex:0];
});
}
视图层次结构中这个不可见元素的存在充当了自动化脚本捕捉屏幕截图的信号。在自动化脚本中,我编写了一个captureScreen 函数,它使用自增计数器来识别屏幕编号。每个递增的屏幕编号都有一个唯一的信号元素。
var screenshotCounter = 0;
function captureScreen() {
screenshotCounter++;
var screenshotSignal = target.frontMostApp().mainWindow().elements().firstWithName("screenshotSignal_" + screenshotCounter);
screenshotSignal.withValueForKey(1, "isVisible");
if ( screenshotSignal.isValid() ) {
UIALogger.logDebug( "Screenshot " + screenshotCounter + " signaled." );
target.captureScreenWithName( "" + screenshotCounter );
return true;
} else {
target.logElementTree();
throw "Did not detect screenshot signal " + screenshotCounter;
}
}
现在在我的脚本中,我可以自动化应用程序以将其放置到正确的位置并调用captureScreen()。然后通过调用上面的signalScreenshot: 方法,当它准备好让脚本捕获屏幕时,它会留给应用程序本身发出信号。效果很好,没有人为的延迟!