Manejando Safari desde Objetive-C

enero 2, 2011

Recientemente me surgió la necesidad de controlar remotamente un explorador web en Windows. En el sistema operativo de Microsoft, gracias a los objetos COM, es posible «instanciar» un objeto InternetExplorer y controlarlo desde código fuente. Gracias a .NET y la Interoperabilidad con los objetos COM, la tarea inicialmente no parece ser para nada complicada, aunque como la compañía de Redmond nos tiene acostumbrados, lidiar con los detalles será una tarea que nos llevará bastante tiempo.

En OSX por su parte este objetivo también esta cubierto, y como pasa habitualmente, de una forma bastante más elegante :D.

La idea es poder controlar, y crear instancias de una aplicación que esta ejecutandose, o que vamos a iniciar. Para ello, como requisito imprescindible, la aplicación debe estar preparada para ser manejada.

El componente clave para que todo esto se pueda realizar son los denominados «Apple Event», que son paquetes de información que se envían en forma de mensaje entre las diferente aplicaciones que se están ejecutando en el Sistema Operativo.

Por ejemplo, si queremos que el Safari en ejecución navegue a una URL, y eso lo queremos hacer desde nuestra aplicación, deberemos enviar un Apple Event que contenga los datos necesarios para llevar a cabo esa acción.

Originalmente, solo era posible enviar eventos usando AppleScript, de hecho, el lenguaje se creo alrededor de dichos eventos. Pero hoy en día se puede utilizar multitud de lenguajes para enviar «Apple Events» como Python, C#, Ruby o Javascript.

Lo que hace posible esta interoperabilidad de lenguajes es lo que se conoce como el Scripting Bridge, como ya hablamos en el blog cuando queríamos usar Python para controlar el iTunes.

A diferencia de la entrada anterior, en esta entrada, vamos a usar Objecitve-C para controlar el Navegador Web, dado que ObjC es un lenguaje compilado, necesitamos tener una referencia de lo que podemos hacer con el «objeto» Safari, de tal manera que podamos compilar nuestro código.

Para ello usamos el comando sdp, que generará un fichero .h y que usaremos para compilar nuestro código. La entrada del comando sdp son los ficheros .sdef, que contienen, en forma de XML, una descripción sobre lo que se puede hacer con el objeto en cuestión.

A nivel de controlar el Navegador, una de las cosas mas utiles es que podemos ejecutar código javascript, con lo que tenemos acceso a todo el documento web que estamos visualizando.

A continuación os dejo un fragmento de código que navega a google, realiza una busqueda usando javascript y muestra el numero de resultados encontrados.

SafariApplication* safari = [SBApplication 
  applicationWithBundleIdentifier:@"com.apple.Safari"];
	
SBElementArray* windows = [safari windows];
SafariTab* currentTab = [[windows objectAtIndex: 0] currentTab];
	
[currentTab setURL:@"http://www.google.com"];
[safari doJavaScript: 
 @"document.getElementsByName('q')[0].value = 'Safari'" 
				  in:currentTab];
[safari doJavaScript: @"document.forms[0].submit()" 
				  in: currentTab];
id result = [safari 
   doJavaScript:@"document.getElementById('resultStats').firstChild.data"
           in:currentTab];
NSLog(@"Results: %@", (NSString*)result);

Un uso en el que esta técnica es útil es cuando queremos hacer pruebas automatizadas de alguna web que estemos realizando. Aunque para estas tareas existe selenium, que si utilizamos firefox, seguramente cubra nuestras necesidades.


Más vale tarde que nunca. Extensiones en Safari.

junio 14, 2010

Pese a que toda la atención del WWDC se la ha llevado el nuevo iPhone, entre el barullo del nuevo teléfono de Apple se ha lanzado una nueva versión del navegador por defecto del OSX, estamos hablando de Safari 5.

Una de las grandes novedades del Safari 5 es que incorpora la posibilidad de ejecutar extensiones, de la misma manera que hace Firefox desde hace mucho tiempo, o mas recientemente Chrome, de hecho, el concepto utilizado es muy similar al usado en el navegador de Google.

Además de para OSX, Safari 5 también esta disponible para Windows, y a diferencia de las versiones anteriores y, basado en mis escasas pruebas, parece que es cuanto menos usable. La buena noticia es que las extensiones son totalmente funcionales también en el sistema operativo de Microsoft.

Hablando ya de las extensiones de Safari, existen varios tipos. Si hablamos de modificar o añadir elementos a la interfaz gráfica de Safari, podemos tener nuevos botones, nuevas barras o nuevos elementos que se añadirán al menú contextual. Aparte de estos elementos, podremos tener extensiones que modifiquen la propia web que estamos visitando, como el típico bloqueador de anuncios o de contenidos Flash

Desde el punto de vista técnico, las extensiones estan programadas usando las típicas técnologias web; HTML5, CSS3 y Javascript

Entrando un poco mas en detalle, típicamente las extensiones estarán formadas por una página HTML que se cargará al incio de la extensión. Esta página la usaremos para colocar las inicializaciones del resto de componentes, así como los eventos que responderán a los elementos gráficos de la propia extension.

Además de esta pagina web, tendremos según los requisitos de esta extension, un conjunto de HTML y CSS que controlarán el aspecto gráfico de nuestra extensión. Por ejemplo, si queremos hacer una barra que muestre algun tipo de información, dicha información estará descrita por un fichero HTML con su correspondiente hoja de estilo, imágenes e iconos.

Si, por otro lado, queremos que nuestra extensión modifique el contenido de la web, necesitaremos tener un conjunto de scripts programados usando Javascript, con el que grácias a la API que nos proporciona el navegador (ofrecida en Javascript tambíen), podremos acceder e incluso modificar el propio contenido de la web que se esta mostrando en el navegador.

Si queremos ponernos manos a la obra, el propio Safari tiene un editor para crear las extensiones. No esperar encontraros un editor de HTML ni nada parecido, en lo que nos ayudará sera en crear la estructura o el «paquete» en el que podremos meter los contenidos de las propias extensiones. Con el Extension builder podremos crear los botones, barras o scripts de las que hemos hablado anteriormente.

Para activarlo, necesitamos ir al menú de preferencias de Safari, y activar el menu de Desarrollador, que por defecto esta desactivado. Una vez activado dicho menú, podremos acceder al Extension builder

El último elemento que necesitamos para crear la extensión es un certificado de desarrollador. Sin este cerficado no podremos ni siquiera instalar una extensión en nuestro navegador. Como vemos, el concepto es muy similar al seguido con el iPhone.

La principal diferencia, es que formar parte del programa de desarrolladores de extensiones de Safari es totalmente gratis. Lo único que tenemos hacer es ir a la web de desarrolladores de apple, http://developer.apple.com y darnos de alta.

Después de rellenar los datos oportunos sólo tendremos que instalar el certificado en el llavero de Mac, o en el almacen de certificados de Windows, para que el Extension Builder lo detecte y nos deje instalar y empaquetar nuestra extensión