2009-09-01 16 views
26

Jestem zmęczony robieniem nowych zrzutów ekranu za każdym razem, gdy zmieniam mój interfejs dla aplikacji na iPhone'a. Chciałbym móc uruchomić skrypt/program/cokolwiek, aby załadować mój plik binarny na symulatorze, a następnie zrobić kilka zrzutów ekranu.Automatyzacja zrzutów ekranu na symulatorze iPhone'a?

Rozwiązanie może być w dowolnym języku ... nie ma to dla mnie znaczenia.

Dzięki!

+2

Chciałbym usłyszeć odpowiedź na to również z urządzenia. –

Odpowiedz

24

Z iPhone SDK 4 można zautomatyzować testy GUI i może wykonać zrzuty ekranu.

Zasadniczo, piszesz skrypt JavaScript, a następnie Instruments (za pomocą szablonu Automation) może uruchomić go na urządzeniu, aby przetestować interfejs użytkownika i może rejestrować dane, zrzut ekranu itp., A także może ostrzec, czy coś jest uszkodzone.

Nie mogłem znaleźć podręcznika, ale w bibliotece referencyjnej SDK wyszukaj klasy UIA* (np. UIAElement).

Jest też wideo demoing to z WWDC, sesja 306.

+1

Oto dokumentacja referencyjna od Apple: https://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Built-InInstruments/Built-InInstruments.html#//apple_ref/doc/uid/TP40004652-CH6-SW75 –

6

prywatny UIGetScreenImage(void) API może być wykorzystywane do przechwytywania zawartości ekranu:

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]; 
} 

należy owinąć go wewnątrz #ifdef więc nie pojawi się na kompilacji uwalniania.

+0

Nie mogłem uruchomić metody UIGetScreenImage. –

+0

Jaki był błąd? – rpetrich

+0

Wydaje się, że UIGetScreenImage nie działa już na symulatorze :((ostatnio próbowałem był na 2.x). Zaktualizowałem kod tak, aby zawierał podstawy ręcznego przechwytywania ekranu ... wydaje się działać całkiem dobrze w przypadku okien portretowych, nie tak dobrze z krajobrazem i nie zawiera paska stanu, ale jest to początek, jeśli go poprawisz, proszę zaktualizuj moją odpowiedź :) – rpetrich

12

Mam takie samo życzenie. Chcę móc zapisywać zrzuty ekranu z kilku ekranów w mojej aplikacji bez całej ręcznej pracy. Jeszcze mnie nie ma, ale zacząłem.

Chodzi o to, aby zakończyć /var/log/system.log, gdzie znajduje się wyjście z instrukcji NSLog. Wyprowadzam dane wyjściowe do programu Pythona. Program python czyta wszystkie linie ze standardowego wejścia i kiedy linia pasuje do określonego wzorca, wywołuje screencapture.

NSLog(@"screenshot mainmenu.png"); 

To spowoduje, że zrzut ekranu o nazwie "XX. główne menu YY.png" będzie tworzony za każdym razem, gdy zostanie wywołany. XX to numer zrzutu ekranu od momentu uruchomienia programu. YY to numer ekranu głównego "menu głównego".

Mam nawet dodaje niepotrzebne funkcje:

NSLog(@"screenshot -once mainmenu.png"); 

To uratuje tylko "XX". Mainmenu.png raz.

NSLog(@"screenshot -T 4 mainmenu.png"); 

uczyni to ekranu po upływie 4 sekund.

Po uruchomieniu aplikacji z prawej wyrębu, screeny z następującymi nazwami mogły powstać:

00. SplashScreen.png 
01. MainMenu 01.png 
03. StartLevel 01.png 
04. GameOver 01.png 
05. MainMenu 02.png 

Spróbować:

  1. dodać kilka oświadczeń NSLog do kodu

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

  3. Uruchom aplikację iPhone w symulatorze

  4. Pobaw się ze swojej aplikacji

  5. Zapraszamy do obejrzenia screenów pokazuje się gdzie program zostanie uruchomiony 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() 

Problemy z tej wersji:

Jeśli chcesz zrobić zrzut ekranu z okna tylko iPhone Simulator, trzeba kliknąć okno iPhone Simulator dla każdego ekranu. screencapture odmawia przechwycenia pojedynczych okien, chyba że jesteś skłonny do interakcji z nim, dziwnej decyzji projektowej dla narzędzia wiersza poleceń.

Aktualizacja: Teraz symulator iPhone'a symulatora (w http://www.curioustimes.de/iphonesimulatorcropper/index.html) działa z poziomu wiersza poleceń. Zamiast więc używać wbudowanego screencapture, pobierz i użyj go zamiast tego. Teraz proces jest całkowicie automatyczny.

+2

Jednym z głównych problemów z tą techniką jest to, że wymaga ona ekranu pracy. Pracuję nad 15-calowym MBP bez zewnętrznego monitora, a to narzędzie nie może przechwytywać zrzutów ekranu z iPada. Wszelkie porady dotyczące sposobów zautomatyzowania tego bez większego ekranu – radven

7

Wewnątrz iPhone Simulator, jest "Kopiuj ekranu" z menu. Zastępuje pozycję menu Kopiuj w menu edycji po przytrzymaniu Control. Skrót klawisza jest Ctrl-Cmd-C Prosty AppleScript może skopiować ScreenShot i zapisać go. Coś podobnego (pracował dla mnie, nawet jeśli jest 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 

Jeśli nie dostać, prosimy o komentarz ...

0

Można również korzystać z niektórych aplikacji do przechwytywania ekranu przechwyć wideo na ekranie symulatora.

Często używam aplikacji Jing.

I nawet używać go do wysyłania wideo, który przedstawia zastosowanie do klientów ...

Powiązane problemy