Convertir un AppleScript en una aplicación para MacOS

AppleScript permite a cualquier usuario de MacOS realizar pequeñas utilidades de forma rápida y sencilla pero el resultado sigue siendo un script que requiere de una aplicación para ser ejecutado. Pero esto no es del todo cierto

El Editor de scripts que ofrece Apple nos permite convertir un script de AppleScript en una aplicación para MacOS.

Un pequeño ejemplo para empezar

Para continuar vamos a partir de un pequeño ejemplo de script que sólo mostrará una alerta por pantalla. El código es el siguiente:


on run
display alert "Esto es un mensaje de prueba."
end run

Una vez escrito nuestro script y tras haberlo guardado con un nombre apropiado es el momento de convertirlo en aplicación.

Exportando un AppleScript como aplicación

En el menú Archivo de la barra de menú del Editor de scripts encontramos la opción de Exportar ….

Al activar la opción de Exportar … aparecerá un cuadro de diálogo para exportar nuestro script. Nos solicitará un nombre, una carpeta de destino y un formato. Ese campo formato es el que nos interesa.

Como formato podremos exportar a script, paquete de scripts, texto y aplicación. Es el formato aplicación el que nos interesa.

Dependiendo de la versión de MacOS que estemos ejecutando el campo formato también estará disponible en el cuadro de diálogo para guardar nuestro script.

Primeros pasos con Swift

Swift es un nuevo lenguaje de programación creado por Apple buscando atraer a nuevos desarrolladores. La propia compañía lo describe en su página oficial de Swift como un lenguaje potente y sencillo de aprender.

Realmente Swift, en comparación con otros lenguajes, tiene una curva de aprendizaje menor y las herramientas proporcionadas por Apple para desarrollar con él lo hacen un lenguaje muy apropiado como primera opción para aprender a programar.

Recientemente Apple ha decidido donar su lenguaje a la comunidad de código abierto lo que permitirá a Swift estar presente en otras plataformas por lo que desarrollar una aplicación para iOS, OSX, Linux y otras plataformas será algo habitual en Swift.

Programando en Swift

Para programar en un lenguaje de programación lo primero que necesitamos son herramientas de desarrollo compatibles con ese lenguaje. Si somos usuarios del sistema operativo MacOS X sólo debemos ir a la aplicación de la Mac AppStore y descargar el entorno de desarrollo de Apple más conocido como xCode.

xCode, como otras aplicaciones específicas para una profesión, no es una herramienta sencilla de comprender con un primer vistazo pero tampoco es una tarea imposible. Iremos conociendo poco a poco esta herramienta junto con el aprendizaje de Swift en una serie de artículos publicados en este blog.

Para programar en otra plataforma distinta a MacOS X hay varias alternativas proporcionadas por la comunidad de código abierto de Swift los cuales trabajan en un compilador para varias plataformas. Actualmente el compilador funciona para el sistema operativo Linux.

Otra alternativa para ir practicando con Swift mientras aprendemos es utilizar una herramienta online creada por IBM para este objetivo. Esta herramienta es conocida como IBM Swift Sandbox y nos ofrece la posibilidad de crear y ejecutar un Playground de Swift a través de nuestro navegador web. Esta herramienta web, aunque recientemente ha solucionado algunos problemas de compatibilidad con dispositivos móviles para poder programar en cualquier momento desde cualquier lugar, presenta algunas barreras de accesibilidad relacionadas con el uso de esta herramienta por parte de usuarios de productos de apoyo por lo que se recomienda utilizar en su lugar xCode o el compilador de Swift para Linux. Esperemos que pronto esté disponible este compilador para otros sistemas operativos.

¿Qué es un Playground de Swift?

Con la creación de Swift Apple también desarrolló nuevas herramientas y conceptos que ayuden a los desarrolladores a realizar su trabajo con mayor efectividad. Una de sus creaciones es el Playground de Swift. Un Playground de Swift es un mini proyecto de aplicación que nos permite probar de forma rápida y controlada partes de código antes de que decidamos introducir ese nuevo código en nuestro proyecto de trabajo. Esto permite probar algoritmos y funciones de una forma cómoda, segura y, además, Apple ha incorporado herramientas de monitorización en los Playgrounds para obtener el rendimiento de los algoritmos ejecutados así como permitir hacer una depuración más intensa de nuestro código.

Nuestro primer programa en Swift

Supongamos que vamos a utilizar xCode para crear nuestro primer programa en Swift. Al abrir xCode aparecerá una ventana de bienvenida. En ella habrá diversos botones, entre ellos encontramos uno que nos permite empezar con un Playground de Swift de forma rápida, es el botón con el título Get started with a playground. Una vez pulsado nos pedirá que demos un nombre a nuestro fichero de Playground y seleccionar una de las plataformas para nuestro Playground: iOS, OSX o TVOS. Tras esto se nos consultará dónde guardar el fichero de nuestro Playground. Con esto xCode ya puede crear el entorno de desarrollo para que empecemos a jugar con nuestro Playground de Swift.

xCode presenta en su interfaz un area de menú con una barra de herramientas con las principales opciones de ejecución, depuración y visualización, y un area de trabajo. Los usuarios de VoiceOver pueden identificar estas zonas fácilmente si utilizan el gesto de dejar de interactuar con el item varias veces (VO+Mayúsculas+flecha arriba). Explorando la ventana desde arriba a la izquierda siguiendo la exploración hacia la derecha encontrará la barra de herramientas, identificada como Toolbar, una zona para controlar las pestañas abiertas en xcode y un area de trabajo. Este area de trabajo es identificada por VoiceOver con el título de ruta de nuestro proyecto, sería algo parecido a MyPlayground.playground split group. Interactuando con el area de trabajo encontraremos varios subcontenedores:
el editor de código, la barra de debug, la zona de debug y varias zonas relacionadas con el diseño visual de la interfaz. Esta zona puede que contenga todos, algunos o ningunos de estos subcontenedores ya que podemos modificar la visualización de xCode en las opciones del menú View de la barra de menú de xCode. Por ahora sólo nos interesa el subcontenedor donde se encuentra el editor de código, VoiceOver lo identificará con el nombre de nuestro fichero en edición; la barra de debug y el panel de debug o depuración, dentro de este panel encontraremos la opción de ejecución para nuestro Playground.

En el editor de código encontramos que ya hay escrito un código de ejemplo:


//: Playground - noun: a place where people can play
import Cocoa
var str = "Hello, playground"

Prueba a borrar todo ese código, escribir el siguiente código y pulsar el botón Execute que hay en la barra de debu:


print("Hola mundo!")

Tras ejecutar el código veremos que el texto Hola mundo! aparece en el area de depuración. ¡Enhorabuena, has creado tu primer programa en Swift!

Puede que sólo encuentres la barra de debug, identificada por VoiceOver como debug bar group y no encuentres el panel de debug, identificado por voiceOver como debug group. Esto puede suceder porque este panel de depuración se puede ocultar. Para hacer que se vea podemos entrar en la barra de debug y pulsar el botón show debug area o usar la opción de la barra de menú de xCode en el menú View o el atajo de teclado ()Comando+Mayúsculas+Y).

Un primer paso de otros muchos

Pensaréis que este programa no vale para nada pero si habéis seguido las instrucciones hasta aquí se supone que habéis adquirido los primeros conocimientos para comenzar a aprender Swift ya que ahora sabéis lo siguiente:

  • Saber escribir código y ejecutar código en un Playground
  • Usar la función print() que muestra un texto por pantalla

En futuros artículos iremos aprendiendo más cosas sobre este lenguaje de programación.

Estructuras condicionales en AppleScript

En AppleScript, al igual que en otros lenguajes de programación, existen ciertas estructuras de código para controlar el flujo de ejecución de nuestro programa. Recordemos que un script es un programa con ciertas características especiales.

La estructura más simple es la sentencia que se puede resumir como una orden que indica al programador a su programa. Un ejemplo sería la línea de código con la sentencia say que hemos visto en el ejemplo de Hola mundo de esta serie de artículos.

Otro ejemplo sería la línea de asignación de un valor a una variable.

Estructuras condicionales

Hasta ahora sólo sabemos crear AppleScripts que ejecuten una sentencia detrás de otra, almacenando información y manipulándola. ¿Pero podemos controlar aún más el flujo de ejecución?

Imaginemos que un trozo de nuestro script se ejecute a partir de una hora determinada, por ejemplo, un aviso para el usuario. Lo primero que debemos hacer es obtener la hora actual. Este ejemplo nos explica cómo hacerlo:


(*
Ejemplo para obtener la hora actual
*)
on run
set fecha to current date
set hora to fecha's hours
end run

En la variable hora se almacena el valor numérico de la hora actual.

Estructura if then

Para poder ejecutar un trozo de código si se cumple una condición debemos utilizar una estructura condicional. La estructura condicional más básica, y común a muchos lenguajes de programación, es la estructura if-then. La traducción al castellano de if, then es si, entonces….

Veamos su sintaxis en AppleScript para entenderla mejor:

if condición a cumplir then
código a ejecutar
end if

En la condición a cumplir se debe indicar una comparación u operación que devuelva un valor verdadero o falso. Ejemplo de esto son operaciones comparativas del tipo A < B, A = B, Nombre = «Jonathan»

Ampliemos nuestro ejemplo anterior para dar un mensaje por voz si la hora es mayor o igual a siete. El ejemplo quedaría así:


(*
Ejemplo para dar un aviso según la hora
*)
on run
-- obtenemos la fecha
set fecha to current date
set hora to fecha's hours
-- según la hora damos el aviso
if hora >= 7 then
say "¡Despierta! Ya es tarde"
end if
end run

En este ejemplo vemos otra forma de incluir comentarios: escribiendo dos caracteres de guión consecutivos (-) indicamos que lo que hay a la derecha de esa línea es un comentario de código. Es una forma de incluir comentarios de forma rápida.

Estructura if then else

El ejemplo anterior sólo nos avisará si son las 7 o más tarde pero no hará nada si es antes de las siete. A veces nos interesa realizar operaciones distintas tanto si se cumple la condición como si se cumple lo contrario. Una forma de hacer esto sería declarar dos estructuras if then con condiciones contrarias. Un ejemplo de esto sería:


(*
Ejemplo 2 para dar un aviso según la hora
*)
on run
-- obtenemos la fecha
set fecha to current date
set hora to fecha's hours
-- según la hora damos el aviso
if hora >= 7 then
say "¡Despierta! Ya es tarde"
end if
if hora < 7 then say "Todavía es temprano. Aprovecha." end if end run

Aunque esta solución pueda considerarse válida resulta poco eficiente y complica el código. Es poco eficiente porque para hacer una acción u otra realiza dos comparaciones. El código resulta más confuso porque ambas estructuras resultan iguales salvo por un signo matemático pudiendo provocar la confusión del programador.

AppleScript, como otros lenguajes, proporciona una solución elegante para cuando queremos ejecutar un trozo de código tanto para cuando se cumple una condición como para cuando se cumple la contraria. Veamos el ejemplo con esta nueva estructura condicional mejorada:


(*
Ejemplo 3 para dar un aviso según la hora
*)
on run
-- obtenemos la fecha
set fecha to current date
set hora to fecha's hours
-- según la hora damos el aviso
if hora >= 7 then
say "¡Despierta! Ya es tarde"
else
say "Todavía es temprano. Aprovecha."
end if
end run

Como se ve en el código aparece la palabra reservada del lenguaje else. Esta partícula nos permite incluir una separación en la estructura condicional para indicar que el código a continuación se ejecutará sólo si no se cumple la condición. La sintaxis completa es:

if condición a cumplir then
código a ejecutar cuando se cumple la condición
else
código a ejecutar si no se cumple la condición
end if

Ahora podemos crear scripts más complejos que realicen operaciones según se cumplan o no ciertas condiciones.

Variables en AppleScript

AppleScript, al igual que en otros lenguajes de programación, nos permite utilizar variables para almacenar y manipular información.
Su uso es muy sencillo. Para declarar y asignar un valor a una variable debemos seguir la siguiente sintaxis:

set nombreDeVariable to valorParaLaVariable

Veamos un ejemplo simple:


on run
set mensaje to "Hola mundo!"
say mensaje
end run

Para reasignar el valor de una variable se sigue la misma sintaxis. En la asignación podemos realizar encadenamiento de cadenas de texto, operaciones matemáticas, etc.

Veamos un ejemplo en la que asignamos el valor 1 a la variable valor, pronunciamos su valor, reasignamos el valor de la variable al valor que tenía antes más una unidad y volvemos a pronunciarlo:


on run
set valor to 1
say valor
set valor to valor + 1
say valor
end run

Problemas de formatos y tipos

Las variables pertenecen a distintos formatos (texto, números enteros, números decimales, estructuras de datos, etc) y formatos (UTF-8, UTF-16, Unicode, etc). Si intentamos manipular variables entre si con tipos o formatos distintos podemos obtener un error. Por ejemplo, la función say, que pronuncia un texto, espera que le pasemos una variable de texto o de números enteros.

Veamos un ejemplo en el que intentamos hacer un script para que nos pronuncie la fecha de hoy:


on run
set fecha to current date
say fecha
end run

Si intentamos ejecutarlo obtendremos el siguiente mensaje de error: No es posible convertir date «sábado 18 de agosto de 2012 09:44:04″ en tipo «class utf8».

Para solucionar este problema deberemos convertir el valor de fecha, que está en el formato de fecha del sistema, a un valor de cadena de texto.

Para convertir el valor de una variable a otro formato debemos realizar una conversión. La conversión en appleScript sigue la siguiente sintaxis:

( variable as tipoAConvertir )

Necesitamos convertir el tipo fecha de la variable fecha a un tipo de cadena de texto. El ejemplo quedaría así:


on run
set fecha to current date
set fechaEnTexto to (fecha as text)
say fechaEnTexto
end run