Eventos de ejecución en aplicaciones creadas con AppleScript

En el artículo Convertir un AppleScript en una aplicación para MacOS aprendimos cómo convertir nuestro script de AppleScript en una aplicación. Esto, entre otras ventajas, nos permite poder ejecutar más rapidamente nuestro script. Pero además podremos acceder a ciertos eventos que se dan en las aplicaciones.

Evento run

El evento run se ejecuta al arrancar la aplicación. Ya hemos visto código que utiliza este evento ya que la función on run se da tanto en aplicaciones como scripts de AppleScript.

Este evento suele utilizarse para inicializar valores para variables, preparar o cargar los recursos necesarios para ejecutar correctamente la aplicación o mostrar la interfaz de bienvenida al usuario.

Evento quit

El evento quit se produce cuando la aplicación va a terminar de ejecutarse y antes de cerrarse dispara el evento quit y ejecuta el código que hayamos codificado para él.

Este evento sólo está disponible cuando convertimos nuestro script en aplicación. Por ejemplo, veamos el siguiente código:


on quit
display alert "Adios a todos!"
end quit

on run
display alert "Hola a todos!"
end run

Si ejecutamos el código en el editor de AppleScript sólo se mostrará el mensaje de saludo pero nunca la despedida. Para poder ver la despedida deberemos convertir nuestro script de AppleScript en una aplicación de MacOS y ejecutarla como una app más. Entonces veremos el mensaje de despedida tras el mensaje de saludo.

Evento idle

El evento idle nos permite ejecutar un código de script cada X segundos. Con esto podemos crear aplicaciones que repitan un script cada cierto tiempo.

Este evento sólo está disponible cuando convertimos nuestro script en aplicación.

Otro requisito de este evento es que requiere más tiempo de ejecución que una aplicación habitual de AppleScript por lo que es recomendable que cuando vayamos a exportar nuestro script para convertirlo en aplicación verifiquemos la casilla Permanecer abierto tras el gestor de ejecución asegurándonos que nuestra ventana de aplicación permanece abierta ejecutando el evento idle hasta que decidamos cerrar la ventana de la aplicación de forma manual.

Al codificar el evento idle debemos finalizar su codificación devolviendo un número que representará el número de segundos necesarios para volver a ejecutar el evento idle. Por ejemplo, el valor 60 se referirá a un minuto y el valor 3600 a una hora. Para devolver ese valor usamos el comando return que nos permite devolver un resultado cuando ejecutamos una función de AppleScript.

Veamos un ejemplo muy sencillo. Vamos a crear una aplicación que reproducirá un sonido cada minuto.


on idle
do shell script "afplay /System/Library/Sounds/Blow.aiff"
return 60
end idle

Ejemplo completo

Nuestro ejemplo deberá realizar las siguientes tareas:

  1. Saludar al inicio
  2. Reproducir un sonido cada 30 segundos
  3. Despedirse al cerrar la ventana de la aplicación

el código sería algo como lo siguiente:


on run
display alert "Hola a todos!"
end run

on quit
display alert "Adios a todos!"
end quit

on idle
do shell script "afplay /System/Library/Sounds/Blow.aiff"
return 30
end idle

Recuerda verificar la casilla Permanecer abierto tras el gestor de ejecución al exportar tu script para convertirlo en aplicación.

Cómo obtener texto del usuario con AppleScript

En anteriores artículos hemos visto diversas opciones para que el usuario pueda elegir qué debe suceder al utilizar uno de nuestros scripts. Pero a veces necesitamos que el usuario nos de información que no hemos podido predecir a la hora de crear nuestro script. Esta información debe ser introducida a través de un campo de texto el cual puede ser utilizado por el usuario para aportar cualquier información que necesite nuestro script y el usuario quiera ofrecer.

Hemos visto ya el comando de AppleScript display dialog. Este comando también nos permite configurarlo para que muestre un campo de texto al usuario. Su sintaxis sería la siguiente:


display dialog "Texto de la pregunta" default answer ""

Obteniendo la respuesta

Como viene siendo habitual para poder hacer algo con la información introducida o seleccionada por el usuario debemos almacenarla en una variable. Podemos hacerlo de la siguiente forma:


set dialogResult to display dialog "?Cual es tu nombre?" default answer ""
set theName to the text returned of (dialogResult)

Primero almacenamos el resultado de la pregunta en la variable dialogResult y luego obtenemos el texto de dialogResult almacenandolo en la variable theName.

Podemos hacer estas dos operaciones en un sólo paso aunque se dificulta la lectura del código de nuestro script. El ejemplo quedaría de la siguiente forma:


set theName to the text returned of (display dialog "?Cual es tu nombre?" default answer "")

Un pequeño ejemplo

Vamos a crear un pequeño script que nos pregunte nuestro nombre y nos muestre un saludo personalizado.


set dialogResult to display dialog "?Cual es tu nombre?" default answer ""
set theName to the text returned of (dialogResult)
set sayHelloText to "Hola " & theName
display alert sayHelloText

Cómo reaccionar a la selección de una lista de elementos en AppleScript

En un artículo anterior vimos cómo permitir al usuario seleccionar un elemento de una lista a través de un cuadro de diálogo. En este artículo veremos cómo reaccionar a la selección del usuario.

Partiremos de nuestro ejemplo de selección de un tipo de comida para pedir a domicilio:


choose from list {"Vegetariana", "Mejicana", "China", "Japonesa", "Mediterranea", "Italiana"} with title "Selección de tipo de comida" with prompt "Selecciona el tipo de comida que más te apetezca" OK button name "Pide ahora!" cancel button name "No tengo hambre" default items {"Mejicana"} multiple selections allowed false empty selection allowed false

Almacenando el resultado

Para gestionar algunas respuestas es necesario que almacenemos los resultados en una variable. Este es el caso del comando choose from list.

En nuestro ejemplo almacenaremos el resultado en la variable resultadoDeDialogo.


set resultadoDeDialogo to choose from list {"Vegetariana", "Mejicana", "China", "Japonesa", "Mediterranea", "Italiana"} with title "Selección de tipo de comida" with prompt "Selecciona el tipo de comida que más te apetezca" OK button name "Pide ahora!" cancel button name "No tengo hambre" default items {"Mejicana"} without multiple selections allowed and empty selection allowed

Reaccionando dependiendo del resultado

Para realizar una u otra operación dependiendo del valor de una variable debemos usar estructuras condicionales en AppleScript para poder codificar todas las posibles acciones que el usuario haga con el cuadro de diálogo.

En nuestro ejemplo el usuario puede realizar las siguientes operaciones:

  • Pulsar el botón de cancelar
  • Seleccionar un elemento y pulsar el botón de aceptar

Gracias a que hemos indicado en el comando choose from list que el usuario no puede seleccionar más de un valor y que el botón de aceptar sólo estará disponible si se ha seleccionado un valor de la lista no tenemos que preocuparnos por otras posibles respuestas por parte del usuario.

Cancelar como resultado

Si el usuario pulsa el botón de cancelar el resultado que obtendremos en la variable resultadoDeDialogo será false. Sabiendo esto podemos codificar qué hacer si el usuario pulsa el botón cancelar.

En nuestro ejemplo mostraremos un mensaje invitando al usuario que vuelva a ejecutar nuestra aplicación cuando tenga hambre.


set resultadoDeDialogo to choose from list {"Vegetariana", "Mejicana", "China", "Japonesa", "Mediterranea", "Italiana"} with title "Selección de tipo de comida" with prompt "Selecciona el tipo de comida que más te apetezca" OK button name "Pide ahora!" cancel button name "No tengo hambre" default items {"Mejicana"} without multiple selections allowed and empty selection allowed

if resultadoDeDialogo = false then
display alert "Vuelve cuando tengas hambre"
end if

Una lista como resultado

Si el usuario pulsa el botón de aceptar el resultado obtenido será una lista de AppleScript con todos los valores seleccionados.

Si hubiesemos permitido al usuario pulsar el botón aceptar sin seleccionar nada obtendríamos como resultado una lista vacía.

Para nuestro ejemplo mostraremos un mensaje indicando que a nosotros nos apetece también ese tipo de comida excepto si es comida vegetariana ya que mostraremos otro mensaje.


set resultadoDeDialogo to choose from list {"Vegetariana", "Mejicana", "China", "Japonesa", "Mediterranea", "Italiana"} with title "Selección de tipo de comida" with prompt "Selecciona el tipo de comida que más te apetezca" OK button name "Pide ahora!" cancel button name "No tengo hambre" default items {"Mejicana"} without multiple selections allowed and empty selection allowed

if resultadoDeDialogo = false then
display alert "Vuelve cuando tengas hambre"
else
set tipoComida to get text 1 of resultadoDeDialogo
if tipoComida = "Vegetariana" then
display alert "No me apetece mucho comida vegetariana ahora. Que aproveche."
else
set cadenaResultado to "A mi también me apetece comer comida " & tipoComida & ". Pide un poco para mi también, por favor."
display alert cadenaResultado
end if
end if

Con todo esto ya podemos crear scripts de AppleScript más complejos en los que el usuario puede controlar cómo reaccionará nuestro programa.

Obtener las respuestas de cuadros de diálogo en AppleScript

En un artículo anterior vimos cómo mostrar cuadros de diálogo para hacer preguntas al usuario. En este artículo veremos cómo recoger la respuesta que ha seleccionado el usuario para poder controlar el comportamiento de nuestro script según lo que seleccione el usuario.

Partiremos del siguiente ejemplo en el que preguntaremos al usuario algo muy simple:


display dialog "¿Tienes hambre?" buttons {"Si", "No"}

Para recoger la respuesta que haya pulsado el usuario debemos construir un control de flujo if then para cada posible respuesta.

Dentro de la estructura if then debemos preguntar si el resultado del botón es igual a una cadena de texto. Esto se consigue con una sintaxis como esta:

button returned of result = "Texto exacto del botón"

Nuestro ejemplo completo quedaría así:


display dialog "¿Tienes hambre?" buttons {"Si", "No"}
if button returned of result = "No" then
display alert "Muy bien, sigue trabajando."
else if button returned of result = "Si" then
display alert "Pues es buena hora para picar algo..."
end if

Cuadros de diálogo en AppleScript para comunicarnos con los usuarios

La comunicación con los usuarios es indispensable para que un programa o script pueda desempeñar su función en la mayoría de casos.

Ya hemos visto en artículos anteriores el uso del comando say que permite verbalizar un texto a través de la síntesis de voz de MacOS pero este método de comunicación con el usuario no es el más accesible para todos ya que puede que el usuario sea sordo o que en el momento de verbalizar el mensaje se esté reproduciendo música, otro sonido u otro mensaje. Por esta razón es recomendable utilizar un método que pueda mostrar en pantalla y de forma accesible los textos que necesitemos comunicar al usuario desde nuestros scripts.

Cuadros de diálogo accesibles para AppleScript

AppleScript nos proporciona el comando display dialog que nos permite mostrar un texto en un cuadro de diálogo. Este cuadro de diálogo es totalmente compatible con todos los productos de apoyo de MacOS.

Veamos un ejemplo simple. Mostraremos el texto Hola mundo! por pantalla:


display dialog "Hola mundo!"

Usando una notificación del sistema en lugar de un cuadro de diálogo

El comando display nos permite mostrar diálogos, alertas y notificaciones del sistema. Por ejemplo, si en lugar de mostrar un cuadro de diálogo quisieramos mostrar una notificación del sistema utilizaríamos display notification. El ejemplo anterior quedaría así:


display notification "Hola mundo!"

Personalización de los botones por defecto en el cuadro de diálogo

Por defecto el comando display dialog incluye un botón de cancelar y un botón de aceptar pero gracias a que display dialog posee multitud de parámetros podemos personalizar su visualización para que se adapte a lo que necesitemos en cada momento.

Por ejemplo, en nuestro caso anterior sólo necesitaríamos mostrar un botón de aceptar para que el usuario cerrase el cuadro de diálogo. El código sería el siguiente:


display dialog "Hola mundo!" buttons {"Aceptar"}

Hemos usado el parámetro buttons para indicar un listado de botones que se mostrarán en el cuadro de diálogo. Para ello creamos una variable de tipo lista de AppleScript.

En otras situaciones quizás necesitemos ofrecer al usuario varias opciones posibles. Por ejemplo, vamos a cambiar el texto de los botones cancelar y aceptar por las posibles respuestas a una pregunta.


display dialog "¿Quiere borrar la información de su disco duro?" buttons {"Si, no hay nada de interés", "No, quiero demasiado a mis datos"} default button "Si, no hay nada de interés" cancel button "No, quiero demasiado a mis datos"

Con el parámetro default button indicamos cuál será el botón seleccionado por defecto y que se pulsará automáticamente si pulsamos la tecla enter en el cuadro de diálogo.

Con el parámetro cancel button indicamos cual será el botón de cancelar.

Los valores para default button y cancel button deberá ser el texto exacto de uno de los botones incluidos en la lista que hemos utilizado para el parámetro buttons. Si indicamos un valor inapropiado el editor de AppleScript nos indicará un error.

El problema de usar display dialog es que sólo podemos mostrar un máximo de 3 botones mediante el uso de estos parámetros. Si intentasemos ejecutar el siguiente script nos saldría un error indicando el mensaje de error de Maximo 3 botones permitidos.


display dialog "¿Quiere borrar la información de su disco duro?" buttons {"Si, no hay nada de interés", "No, quiero demasiado a mis datos", "No estoy seguro, preguntame mañana", "Aún me lo estoy pensando"} default button "Si, no hay nada de interés" cancel button "No, quiero demasiado a mis datos"

Más adelante veremos otro método para que el usuario pueda elegir entre más de tres opciones.

Utilizando un lenguaje más visual y accesible

Para el ejemplo anterior en el que consultamos si el usuario desea borrar el disco duro es muy aconsejable que este tipo de preguntas vengan acompañadas de un icono indicando si es un error, un aviso de seguridad, una pregunta, etc. Podemos añadir iconos a nuestro cuadro de diálogo incluyendo with icon al final de nuestro comando para mostrar la pregunta. El código de nuestro ejemplo quedaría así:


display dialog "¿Quiere borrar la información de su disco duro?" buttons {"Si, no hay nada de interés", "No, quiero demasiado a mis datos"} default button "Si, no hay nada de interés" cancel button "No, quiero demasiado a mis datos" with icon caution

Los valores por defecto para el parámetro icon son stop, note y caution. También podemos utilizar un icono personalizado por nosotros pero no veremos esta posibilidad en este artículo.

Tiempo límite para nuestros mensajes y diálogos

Por alguna razón podríamos estar interesados en que nuestro diálogo sólo se muestre un número determinado de segundos. Con el parámetro giving up after podemos indicar el número de segundos que el usuario tendrá para poder visualizar e interactuar con el cuadro de diálogo.

Un ejemplo podría ser el siguiente:


display dialog "¡Rápido, conteste en menos de 5 segundos! ¿Quiere borrar la información de su disco duro?" buttons {"Si, no hay nada de interés", "No, quiero demasiado a mis datos"} default button "Si, no hay nada de interés" cancel button "No, quiero demasiado a mis datos" with icon caution giving up after 5

Añadiendo un título a nuestro cuadro de diálogo

Un título para nuestro cuadro de diálogo puede ser necesario para que el usuario se ponga en contexto con lo que le estamos preguntando.

Para indicar un título en nuestro cuadro de diálogo podemos utilizar el parámetro with title. Nuestro ejemplo quedaría así:


display dialog "¡Rápido, conteste en menos de 5 segundos! ¿Quiere borrar la información de su disco duro?" buttons {"Si, no hay nada de interés", "No, quiero demasiado a mis datos"} default button "Si, no hay nada de interés" cancel button "No, quiero demasiado a mis datos" with icon caution with title "Pregunta para borrado del disco" giving up after 5

Con lo visto en este artículo ya podemos comunicarnos con nuestros futuros usuarios de forma más accesible.