Автоматизировать скриншоты на iPhone Simulator? - PullRequest
27 голосов
/ 01 сентября 2009

Мне надоело делать новые снимки экрана каждый раз, когда я меняю свой интерфейс для приложения iPhone. Я хотел бы иметь возможность запустить скрипт / программу / что угодно, чтобы загрузить мой двоичный файл на симуляторе, а затем сделать несколько снимков экрана.

Решение может быть на любом языке ... для меня это не имеет значения.

Спасибо!

Ответы [ 6 ]

25 голосов
/ 21 июня 2010

С помощью iPhone SDK 4 вы можете автоматизировать тесты графического интерфейса и снимать скриншоты.

По сути, вы пишете сценарий Javascript, а затем Instruments (используя шаблон автоматизации) может запускать его на устройстве для проверки пользовательского интерфейса, а также может регистрировать данные, снимки экрана и т. Д., А также может оповещать, если что-то сломалось.

Я не смог найти справочник для него, но в библиотеке ссылок SDK найдите UIA* классов (например, UIAElement).

Есть также видео, демонстрирующее это из WWDC, сессия 306.

12 голосов
/ 16 октября 2009

У меня такое же желание. Я хочу иметь возможность сохранять скриншоты с нескольких экранов в моем приложении без всякой ручной работы. Я еще не там, но я начал.

Идея состоит в том, чтобы привязать /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

Дайте ему попытку:

  1. Добавьте несколько операторов NSLog в ваш код

  2. $ tail -f -n0 /var/log/system.log | ./grab.py

  3. Запустите приложение iPhone в симуляторе

  4. Поиграйте с вашим приложением

  5. Посмотрите на скриншоты, показывающие, где вы запустили программу 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) работает из командной строки. Поэтому вместо использования встроенного снимка экрана загрузите его и используйте вместо него. Так что теперь процесс полностью автоматический .

7 голосов
/ 25 июня 2010

Внутри iPhone Simulator есть пункт меню «Экран копирования». Он заменяет пункт меню «Копировать» в меню редактирования, когда вы удерживаете нажатой клавишу «Control». Нажатие клавиши является Ctrl-Cmd-C Простой AppleScript может скопировать снимок экрана и сохранить его. Что-то вроде (у меня это сработало, даже если это это хаки):

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

Если вы не получили его, пожалуйста, прокомментируйте ...

6 голосов
/ 01 сентября 2009

Частный UIGetScreenImage(void) API может использоваться для захвата содержимого экрана:

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, чтобы он не появился в сборке выпуска.

1 голос
/ 27 января 2013

Если вы заинтересованы в автоматической смене языка симулятора и типа устройства автоматически, я разработал несколько скриптов, которые делают это: http://github.com/toursprung/iOS-Screenshot-Automator

0 голосов
/ 28 июня 2010

Вы также можете использовать приложение для захвата экрана для захвата видео на экране симулятора.

Я часто пользуюсь приложением Jing.

Я даже использую его для отправки видео, которое представляет приложение клиентам ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...