2009-09-01 10 views
26

Estoy cansado de tomar nuevas capturas de pantalla cada vez que cambio mi UI para mi aplicación de iPhone. Me gustaría poder ejecutar un script/programa/lo que sea para cargar mi binario en el simulador y luego tomar algunas capturas de pantalla.¿Automatiza las capturas de pantalla en el simulador de iPhone?

La solución puede ser en cualquier idioma ... no me importa.

Gracias!

+2

Me gustaría escuchar una respuesta para hacer esto desde el dispositivo también. –

Respuesta

24

Con iPhone SDK 4 puede automatizar las pruebas de GUI, y puede tomar capturas de pantalla para usted.

Básicamente, escribe una secuencia de comandos Javascript, y luego Instrumentos (usando la plantilla de Automatización) puede ejecutarlo en el dispositivo para probar la interfaz de usuario, y puede registrar datos, captura de pantalla, etc. y también puede alertar si algo no funciona.

No pude encontrar una guía de referencia para ello, pero en la biblioteca de referencia del SDK busco clases UIA* (como UIAElement).

También hay un video demos esto desde la WWDC, sesión 306.

+1

Aquí está la documentación de referencia de Apple: https://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Built-InInstruments/Built-InInstruments.html#//apple_ref/doc/uid/TP40004652-CH6-SW75 –

6

La privada UIGetScreenImage(void) API se puede utilizar para capturar el contenido de la pantalla:

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

Asegúrese de envolver dentro de un #ifdef por lo que no aparece en la versión de lanzamiento.

+0

No pude obtener el método UIGetScreenImage para que funcione. –

+0

¿Cuál fue el error? – rpetrich

+0

Parece que UIGetScreenImage ya no funciona en el simulador :((la última vez que lo intenté fue en 2.x). He actualizado el código para incluir los conceptos básicos de la captura manual de pantalla ... parece funcionar bastante bien con las ventanas verticales, sin embargo no tan bien con el paisaje y no incluye la barra de estado, pero es un comienzo. Si lo mejora, actualice mi respuesta :) – rpetrich

12

Tengo el mismo deseo. Quiero poder guardar capturas de pantalla de algunas pantallas en mi aplicación sin todo el trabajo manual. Todavía no he llegado, pero he comenzado.

La idea es rastrear /var/log/system.log, donde va la salida de las declaraciones NSLog. Canalizo la salida a un programa python. El programa python lee todas las líneas de stdin y cuando la línea coincide con un patrón específico, llama a captura de pantalla.

NSLog(@"screenshot mainmenu.png"); 

que provocará una captura de pantalla llamado "XX. Mainmenu YY.png" que se crea cada vez que se llama. XX es el número de la captura de pantalla desde que comenzó el programa. YY es el número de la captura de pantalla "mainmenu".

Incluso me han añadido algunas características innecesarias:

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

Esto sólo ahorrará "XX mainmenu.png." Una vez.

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

Esto hará que la captura de pantalla después de un retraso de 4 segundos.

Después de ejecutar una aplicación con el registro correcto, si lo hubieran creado capturas de pantalla con los siguientes nombres:

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

darle una oportunidad:

  1. Añadir algunas declaraciones NSLog a su código

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

  3. Comience su aplicación para el iPhone en el simulador

  4. jugar con su aplicación

  5. echar un vistazo a las capturas de pantalla que muestran hasta donde se inició el programa grab.py

agarrar.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() 

Problemas con esta versión:

Si usted quiere tomar una captura de pantalla de la ventana única simulador de iPhone, usted tiene que hacer clic en el simulador de iPhone ventana para cada pantalla. screencapture se niega a capturar ventanas individuales a menos que esté dispuesto a interactuar con ella, una decisión de diseño extraña para una herramienta de línea de comandos.

Actualización: Ahora iPhone simulator cropper (en http://www.curioustimes.de/iphonesimulatorcropper/index.html) funciona desde la línea de comandos. Entonces, en lugar de usar la captura de pantalla integrada, descárgala y úsala en su lugar. Entonces, ahora el proceso es completamente automático.

+2

Un problema importante con esta técnica es que requiere una pantalla de contratación para funcionar. Hago mi desarrollo en un MBP de 15 "sin un monitor externo, y esta herramienta no puede capturar capturas de pantalla del tamaño de un iPad. ¿Algún consejo sobre cómo automatizar esto sin una pantalla más grande? – radven

7

Dentro del simulador de iPhone, hay un elemento de menú "Copia de pantalla". Reemplaza el elemento de menú Copiar en el menú de edición cuando mantiene presionado Control. La combinación de teclas es Ctrl-Cmd-C Un simple AppleScript podría copiar una captura de pantalla y guardarla. Algo así como (que trabajó para mí, incluso si es 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 

Si no lo consigue, por favor, comentario ...

0

También puede utilizar un poco de la captura de pantalla de la aplicación de captura un video en la pantalla del Simulador.

Uso mucho la aplicación Jing.

incluso lo uso para enviar un vídeo que presenta la aplicación a los clientes ...

Cuestiones relacionadas