Автоматизировать скриншоты на iPhone Simulator?
Я устал снимать новые скриншоты каждый раз, когда я меняю свой интерфейс для своего iPhone-приложения. Я хотел бы иметь возможность запускать script/program/whatever для загрузки моего бинарного файла на симуляторе, а затем сделать несколько скриншотов.
Решение может быть на любом языке... для меня это не имеет значения.
Спасибо!
Ответы
Ответ 1
С iPhone SDK 4 вы можете автоматизировать тесты GUI, и для вас могут быть скриншоты.
В принципе, вы пишете Javascript script, а затем инструменты (с использованием шаблона автоматизации) могут запускать его на устройстве для проверки пользовательского интерфейса, а также записывать данные, снимок экрана и т.д., а также может оповещать, если что-то сломалось.
Я не смог найти справочное руководство для него, но в справочной библиотеке SDK вы найдете классы UIA*
(например, UIAElement
).
Также есть видео, демонстрирующее это из WWDC, сеанс 306.
Ответ 2
У меня такое же желание. Я хочу иметь возможность сохранять скриншоты с нескольких экранов в моем приложении без всякой ручной работы. Я еще не там, но я начал.
Идея состоит в том, чтобы tail/var/log/system.log, где выводятся инструкции NSLog. Я подключаю вывод к программе python. Программа python считывает все строки из stdin и когда строка соответствует определенному шаблону, она вызывает screencapture.
NSLog(@"screenshot mainmenu.png");
Это вызовет создание скриншота с именем "XX. mainmenu YY.png" при каждом вызове. XX - это номер снимка экрана с момента запуска программы. YY - это номер снимка "mainmenu".
Я даже добавил некоторые ненужные функции:
NSLog(@"screenshot -once mainmenu.png");
Это сохранит только "XX. mainmenu.png" один раз.
NSLog(@"screenshot -T 4 mainmenu.png");
Это сделает снимок экрана после задержки 4 секунды.
После запуска приложения с правильным протоколированием могут быть созданы скриншоты со следующими именами:
00. SplashScreen.png
01. MainMenu 01.png
03. StartLevel 01.png
04. GameOver 01.png
05. MainMenu 02.png
Попробуйте:
-
Добавьте в свой код некоторые инструкции NSLog
-
$tail -f -n0/var/log/system.log |./grab.py
-
Запустите приложение iPhone в симуляторе
-
Играйте со своим приложением
-
Посмотрите на скриншоты, показывающие, где вы запустили программу grab.py
grab.py:
#!/usr/bin/python
import re
import os
from collections import defaultdict
def screenshot(filename, select_window=False, delay_s=0):
flags = []
if select_window:
flags.append('-w')
if delay_s:
flags.append('-T %d' % delay_s)
command_line = 'screencapture %s "%s"' % (' '.join(flags), filename)
#print command_line
os.system(command_line)
def handle_line(line, count=defaultdict(int)):
params = parse_line(line)
if params:
filebase, fileextension, once, delay_s = params
if once and count[filebase] == 1:
print 'Skipping taking %s screenshot, already done once' % filebase
else:
count[filebase] += 1
number = count[filebase]
count[None] += 1
global_count = count[None]
file_count_string = (' %02d' % number) if not once else ''
filename = '%02d. %s%s.%s' % (global_count, filebase, file_count_string, fileextension)
print 'Taking screenshot: %s%s' % (filename, '' if delay_s == 0 else (' in %d seconds' % delay_s))
screenshot(filename, select_window=False, delay_s=delay_s)
def parse_line(line):
expression = r'.*screenshot\s*(?P<once>-once)?\s*(-delay\s*(?P<delay_s>\d+))?\s*(?P<filebase>\w+)?.?(?P<fileextension>\w+)?'
m = re.match(expression, line)
if m:
params = m.groupdict()
#print params
filebase = params['filebase'] or 'screenshot'
fileextension = params['fileextension'] or 'png'
once = params['once'] is not None
delay_s = int(params['delay_s'] or 0)
return filebase, fileextension, once, delay_s
else:
#print 'Ignore: %s' % line
return None
def main():
try:
while True:
handle_line(raw_input())
except (EOFError, KeyboardInterrupt):
pass
if __name__ == '__main__':
main()
Проблемы с этой версией:
Если вы хотите сделать снимок экрана только окна iPhone Simulator, вам нужно щелкнуть окно iPhone Simulator для каждого снимка экрана. screencapture отказывается захватывать отдельные окна, если вы не хотите взаимодействовать с ним, странное решение для дизайна инструмента командной строки.
Обновление: Теперь iPhone-симулятор (в http://www.curioustimes.de/iphonesimulatorcropper/index.html) работает из командной строки. Поэтому вместо использования встроенного screencapture загрузите и используйте его вместо этого. Итак, теперь процесс полностью автоматический.
Ответ 3
Внутри iPhone Simulator есть пункт меню "Копировать экран". Он заменяет пункт меню "Копировать" в меню редактирования, когда вы удерживаете Control.
Клавиша Ctrl-Cmd-C
Простой AppleScript мог скопировать ScreenShot и сохранить его. Что-то вроде (это сработало для меня, даже если оно hacky):
tell application "iPhone Simulator" to activate
tell application "System Events"
keystroke "c" using {command down, control down}
end tell
tell application "Preview" to activate
tell application "System Events"
keystroke "n" using {command down}
keystroke "w" using {command down}
delay 1
keystroke return
delay 1
keystroke "File Name"
keystroke return
end tell
Если вы этого не поняли, прокомментируйте...
Ответ 4
Частный API UIGetScreenImage(void)
может использоваться для захвата содержимого экрана:
CGImageRef UIGetScreenImage();
void SaveScreenImage(NSString *path)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGImageRef cgImage = UIGetScreenImage();
void *imageBytes = NULL;
if (cgImage == NULL) {
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
imageBytes = malloc(320 * 480 * 4);
CGContextRef context = CGBitmapContextCreate(imageBytes, 320, 480, 8, 320 * 4, colorspace, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorspace);
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
CGRect bounds = [window bounds];
CALayer *layer = [window layer];
CGContextSaveGState(context);
if ([layer contentsAreFlipped]) {
CGContextTranslateCTM(context, 0.0f, bounds.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
}
[layer renderInContext:(CGContextRef)context];
CGContextRestoreGState(context);
}
cgImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
}
NSData *pngData = UIImagePNGRepresentation([UIImage imageWithCGImage:cgImage]);
CGImageRelease(cgImage);
if (imageBytes)
free(imageBytes);
[pngData writeToFile:path atomically:YES];
[pool release];
}
Обязательно оберните его внутри #ifdef
, чтобы он не отображался в сборке выпуска.
Ответ 5
Если вы заинтересованы в автоматическом изменении языка симулятора и типа устройства, я разработал несколько сценариев, которые делают это: http://github.com/toursprung/iOS-Screenshot-Automator
Ответ 6
Вы также можете использовать приложение захвата экрана для захвата видео на экране Simulator.
Я использую приложение Jing много.
Я даже использую его для отправки видео, которое представляет приложение для клиентов...