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.

Variables locales, globales y propiedades en AppleScript

En otros artículos hemos visto las variables en AppleScript y cómo manipularlas.

Las variables en AppleScript pueden tener un ámbito local o global. Esto significa que una variable puede ser utilizada dentro de la función donde ha sido declarada (ambito local) o puede ser utilizada en cualquier parte de nuestro script de AppleScript (ámbito global).

Todas las variables globales y locales son reinicializadas cuando se ejecuta un script por lo que en las variables sólo podremos almacenar información que vaya a ser utilizada en el momento de ejecutar ese script.

Declaración de variables locales y globales

Las variables locales no es necesario declararlas con anterioridad ya que por defecto cualquier variable utilizada a través del comando set es declarada como local.

En cambio las variables globales deben ser declaradas al comienzo del script utilizando el comando global. Un ejemplo puede ser:


-- Declaramos la variable
global miVariableGlobal

on run
— Usamos la variable global
set miVariableGlobal to 1
end run

Persistencia de información en AppleScript

A veces podemos necesitar guardar información para la ejecución de un AppleScript entre una y la siguiente ejecución. Para este motivo AppleScript nos proporciona un tipo especial de variables: las propiedades

Las propiedades, como las variables globales, se declaran al comienzo del script pero a diferencia de las variables globales, al declararlas es necesario indicar un valor inicial. Por ejemplo:


-- Declaramos la variable
global miVariableGlobal
-- Declaramos la propiedad
property propertyVar : 1

A la hora de manipular una propiedad se hace al igual que con una variable utilizando el comando set

Ejemplo

Vamos a ver un ejemplo simple en el que veremos cómo se comportan las variables locales, globales y propiedades con cada nueva ejecución del script. Para ello abre el editor de scripts de Macos, escribe el siguiente código y utiliza la opción run unas cuantas veces para ver cómo varia la información con cada nueva ejecución.


-- Las propiedades y variables globales se declaran al comienzo del script

global globalVar
property propertyVar : 1

on run
— Inicializamos los valores
set localVar to 1
set globalVar to 1
set localVarText to localVar as text
set globalVarText to globalVar as text
set propertyVarText to propertyVar as text

— Preparamos el texto a verbalizar
set result to «El valor local es » & localVarText & «, el global es » & globalVarText & » y el valor de propiedad es » & propertyVarText
— Verbalizamos el resultado
say result

— Actualizamos los valores para la siguiente ejecución
set localVar to localVar + 1
set globalVar to globalVar + 1
set propertyVar to propertyVar + 1
end run

Ejecutar scripts de AppleScript desde el terminal de MacOS

En determinadas ocasiones quizás nos encontremos con la necesidad de ejecutar un AppleScript desde otra aplicación o servicio. El Terminal de MacOS nos permite realizar multitud de operaciones relacionadas con el sistema operativo de nuestro ordenador y una de ellas es solicitar al int&eeacute;erprete de AppleScript que ejecute un fichero scpt que es la extensión para los ficheros de código de scripts de AppleScript.

Para conseguir que el terminal utilice el intérprete de AppleScript debemos utilizar el comando osascript

Su sintáxis es la siguiente:


osascript rutaAlFicheroDeScript/nombreDelFichero.scpt

Por ejemplo, si queremos ejecutar el fichero miScript.scpt que está en la carpeta de descargas de nuestro usuario el comando sería:


osascript /Users/miUsuario/Downloads/miScript.scpt

Enviar mensajes de texto con la aplicación Mensajes de MacOS utilizando AppleScript

La aplicación mensajes nos permite enviar texto, audio e imágenes a otros dispositivos de Apple. Esta aplicación puede ser operada a través de AppleScript para realizar multitud de tareas.

El envío de mensajes de texto con esta aplicación es relativamente sencillo utilizando AppleScript.

Para enviar un mensaje de texto debemos indicar desde qué cuenta de Mensajes queremos enviar el texto y a quién queremos enviarlo.

Por ejemplo, supongamos que queremos enviar el mensaje Hola mundo! al usuario con número de teléfono +34555555555. Es necesario añadir el código de país para que Mensajes encuentre al usuario correcto.

Nuestra cuenta de correo configurada para el protocolo Mensajes es prueba@icloud.com y el valor que se debe utilizar para indicar al script que es una cuenta de servicio es: E:prueba@icloud.com

El código sería el siguiente:


set destinatario to "+34555555555"
set textoAEnviar to "Hola mundo!"
set remitente to "E:prueba@icloud.com"
tell application "Messages"
set theBuddy to buddy destinatario of service remitente
send textoAEnviar to theBuddy
end tell

Solucionando problemas

con ciertas operaciones con la aplicación Mensajes y AppleScript podemos obtener algunos mensajes de error. Por ejemplo: si intentamos enviarnos un mensaje a nosotros mismos podríamos obtener un mensaje de error como el siguiente:


Messages ha detectado un error: No puede obtenerse buddy id «C26717C6-647B-48A1-B963-14A4EC5CD5FA:+34555555555».

Este mensaje de error nos indica que no se ha podido crear la conversación desde AppleScript. La solución pasa por abrir la aplicación Mensajes y abrir nosotros mismos una conversación con nuestro propio telf&eeacute;fono y enviarnos un mensaje. Tras esto no debemos borrar esa nueva conversación y probar de nuevo a ejecutar nuestro script de AppleScript. El mensaje de nuestro script debería enviarse sin problemas.

Abrir y comprobar si una aplicación está abierta en MacOS con AppleScript

Con AppleScript podemos enviar y manipular aplicaciones para conseguir realizar tareas pero para que estas aplicaciones puedan realizar dichas tareas deben estar abiertas. Por esta razón, en muchas ocasiones, debemos asegurarnos dentro del código de nuestro script si la aplicación está abierta y de no ser así abrirla para poder operar con ella.

Preguntando si la aplicación está en ejecución

Ya vimos en el artículo estructuras condicionales en AppleScript cómo crear una estructura condicional para hacer preguntas con nuestro script.

Con una sentencia if then podemos preguntar a una aplicación si está activa o no. Por ejemplo, el siguiente código pregunta si la aplicación Mensajes est´ activa:


if application "Messages" is running then
-- código a ejecutar cuando mensajes está abierto
end if

También podemos consultar si la aplicación no está disponible:


if application "Messages" is not running then
-- código a ejecutar cuando la aplicación no está disponible
end if

Abriendo la aplicación

En AppleScript con el comando tell podemos enviar diversos comandos a las aplicaciones. Uno de estos comandos es ordenarle que se abra. Por ejemplo, abramos la aplicación mensajes:


tell application "Messages" to activate

Con tell también podemos crear bloques de código para enviar una serie de comandos a una aplicación. Su sintáxis es la siguiente:


tell application "Nombre de aplicación
-- Código a ejecutar con la aplicación
end tell

En muchas ocasiones es recomendable incluir pausas (comando delay) entre una operación y otra que enviemos a una aplicación para darle tiempo a la aplicación a procesar el comando y obtener un resultado.

Cerrando la aplicación

También podemos ordenar a una aplicación que se cierre. El comando en lugar de activate es quit. El código es el siguiente:


tell application "Messages" to quit

Ejemplo completo

En un script real que quisiera utilizar la aplicación mensajes para algo la estructura del código debería seguir la siguiente lógica:

  • Si la aplicación no está activa
  • Entonces abre la aplicación
  • Opera con la aplicación mensajes con la tranquilidad de que se sabe que recibirá nuestros comandos porque sabemos que está abierta

Nuestro script final quedaría de la siguiente forma:


if application "Messages" is not running then
tell application "Messages" to activate
end if

Esta práctica de seguridad es muy recomendable para asegurarnos de que nuestros scripts funcionan siempre como se espera.