Los eventos de Apple son el mecanismo de comunicación entre procesos basado en mensajes de Mac OS , que apareció por primera vez en System 7 y que es compatible con todas las versiones del Mac OS clásico desde entonces y con macOS . Los eventos de Apple describen eventos de "alto nivel" como "abrir documento" o "imprimir archivo", mientras que los sistemas operativos anteriores admitían eventos mucho más básicos, a saber, "hacer clic" y "pulsar tecla". Los eventos de Apple forman la base del sistema de scripts de Mac OS, la Open Scripting Architecture (cuyo lenguaje principal es AppleScript ).
El punto de partida es un formato de descriptor extensible y de tipado dinámico llamado AEDesc , que es simplemente un código OSTypeinte
que especifica el tipo de datos, junto con un bloque de datos dependientes del tipo. Por ejemplo, el código OSType indica que los datos eran un entero con signo de cuatro bytes en formato big-endian .
Además de los códigos de tipo predefinidos para varios tipos simples comunes, existen dos tipos de descriptores estructurados predefinidos: un AERecord , que tiene un tipo de datos reco
(registro), y un AEList con un tipo list
(lista o matriz). La estructura interna de estos contiene AEDescs anidados de forma recursiva, mientras que el AERecord también asocia cada elemento con un ID de campo de registro único, que es un OSType. El Apple Event Manager proporciona llamadas a la API para construir estas estructuras, así como para extraer su contenido y consultar el tipo de contenido que contienen.
El Apple Event Manager también admite conversiones , que convierten AEDescs de un tipo de datos a otro. Además de las conversiones estándar, por ejemplo entre tipos enteros y reales, las aplicaciones pueden instalar sus propias devoluciones de llamadas de controlador de conversión , que gestionan las conversiones hacia y desde tipos de datos personalizados.
Un evento de Apple propiamente dicho es un AERecord con campos que dependen del propósito del evento. Además, tiene atributos (que son distintos de los campos de registro, que ahora se denominan parámetros del evento) de un conjunto predefinido por el Administrador de eventos de Apple. Estos especifican lo que se supone que debe hacer el evento (a través de la clase de evento y el ID de evento ), la dirección de destino a la que se enviará el evento (que podría ser un proceso en la máquina local o remota) y varias otras opciones para manejarlo. Las máquinas remotas inicialmente tenían que conectarse a través de AppleTalk , pero Mac OS 9 agregó la opción de conexiones a través de TCP/IP .
Después de enviar un evento de Apple a su proceso de destino, el proceso de envío puede optar por recibir una respuesta a un evento de Apple. Esta puede contener diversos fragmentos de información devueltos desde el destino sobre el procesamiento del evento original, incluido un código de error que indica éxito/error, cualquier información solicitada por el evento original y/u otra información apropiada.
Los eventos de Apple son la base del modelo de objetos AppleEvent , que a su vez es la base de OSA y AppleScript . A partir de 2016 [actualizar], la implementación oficial de la API de Apple Event Manager está disponible en C y sus descendientes, incluido C++ . También se proporcionan enlaces oficiales para Objective-C y Swift a través de la API Cocoa . También existen enlaces no oficiales para otros lenguajes (con distintos grados de limitación), incluidos Perl , UserTalk , Ruby y Python .
El modelo de objetos AppleEvent ( AEOM ) era un conjunto de protocolos creados sobre AppleEvents mediante el cual las aplicaciones que se ejecutaban en Mac OS y macOS clásicos podían controlar las funciones de cada una. Las aplicaciones que implementaban alguna parte del AEOM se denominaban programables porque podían controlarse mediante AppleScript . Desafortunadamente, la compatibilidad con la programación siguió siendo irregular e inconsistente a lo largo de la historia del Mac OS clásico.
El AEOM proporcionó una capa sintáctica bajo la cual cualquier aplicación podía publicar sus objetos internos, lo que permitía manipularlos de forma estandarizada. A diferencia de otros conceptos de sonido similar, como ToolTalk , había una distinción clara y ortogonal entre sustantivos y verbos ; por lo tanto, en lugar de proporcionar comandos separados para "cerrar documento" y "cerrar ventana", había un único verbo "cerrar" que podía tomar referencias a objetos "documento" o "ventana", o cualquier otro objeto que la aplicación publicara.
Los objetos que una aplicación ponía a disposición a través de su soporte AEOM se organizaban en una jerarquía. En la parte superior se encontraba la propia aplicación, a la que se hacía referencia mediante un descriptor de objeto nulo. Se hacía referencia a otros objetos especificando (de forma recursiva) su objeto padre, junto con otra información que lo identificaba como hijo de ese padre, todo ello recopilado en un AERecord . Los padres proporcionaban un iterador para enumerar a sus hijos, o a los hijos de una determinada clase, lo que permitía a las aplicaciones abordar un conjunto de elementos. El sistema era, en general, similar al Modelo de objetos de documento utilizado en XML , aunque con algunas diferencias en los patrones de acceso.
Cada objeto podría tener elementos y propiedades ; los elementos eran otros objetos que se podían crear o eliminar, mientras que las propiedades no se podían crear ni eliminar, pero tenían valores que se podían consultar o cambiar. Por ejemplo, la aplicación podría tener uno o más elementos de ventana que representan ventanas que muestran el contenido de los documentos abiertos en ese momento. Estas ventanas podrían tener propiedades como su título, posición y tamaño.
Una aplicación podía definir verbos personalizados para operar sobre sus objetos. El AEOM también especificaba varios verbos estándar que (se esperaba) las aplicaciones implementarían de manera consistente, como abrir, cerrar, crear elemento, eliminar, establecer datos y obtener datos. Cada verbo se definía como un AppleEvent de un tipo y clase específicos, junto con parámetros particulares de tipos particulares que se esperaba que estuvieran presentes. Por ejemplo, el evento "obtener datos" era el medio estándar para obtener el valor de una propiedad: tomaba esencialmente un parámetro, que era un descriptor de objeto que identificaba la propiedad que se iba a consultar. El valor de esa propiedad se devolvería en el evento de respuesta. El evento "establecer datos" tomaba dos parámetros, el descriptor de objeto para la propiedad que se iba a establecer y el nuevo valor para la propiedad; solo se esperaba que el evento de respuesta devolviera un estado de éxito o un código de error de falla.
Toda la arquitectura de AppleEvent identifica elementos mediante códigos OSType de cuatro bytes , evitando cuidadosamente palabras o frases reales en inglés (o en cualquier otro idioma). En cambio, la correspondencia entre los códigos internos de AppleEvent y las descripciones externas en lenguaje natural se especifica a través del recurso aete ( AppleEvent Terminology Extension ), siendo la "extensión" la terminología estándar incorporada en el propio AppleScript. Una aplicación puede proporcionar múltiples recursos "aete" para múltiples idiomas, de acuerdo con el diseño multilingüe original del propio AppleScript.
Por ejemplo, considere la siguiente secuencia de AppleScript que controla una aplicación de dibujo ficticia:
Decirle a la aplicación "ScriptableDraw" que establezca el color de fondo de la ventana "Nuevo dibujo" al color de fondo de la ventana "Dibujo antiguo" .
En realidad, esto implica el envío de dos AppleEvents a la aplicación de destino (y la recepción de sus respuestas correspondientes): primero, se envía un evento get-data para recuperar la propiedad de color de fondo de la ventana identificada con el nombre "Old Drawing"; luego, se envía un evento set-data para aplicar el valor devuelto como la propiedad de color de fondo de la ventana llamada "New Drawing".
Dado que este tipo de patrón de acceso era típico, AppleScript hizo un uso generalizado de la tell
instrucción, que cambiaba el contexto al objeto nombrado de una manera similar a la with
instrucción que se encuentra en Visual Basic o Pascal . Todos los comandos después del tell
correspondiente end tell
se enviarían al objeto nombrado en el tell
, en lugar del objeto predeterminado, que era la aplicación actual.
Los descriptores de objetos permitían la identificación de objetos de varias maneras. La más interesante era usar una cláusula where (que se traducía a la terminología de AppleScript como una expresión de filtro ). Por ejemplo, el SDK de AppleScript 1.0 se entregaba con el código fuente de una aplicación de ejemplo llamada Scriptable Text Editor, que respondería a scripts como:
Dile a la aplicación "Editor de texto programable" Dile a la ventana "Documento de ejemplo" Establece el estilo de texto de cada palabra cuya longitud > 7 en negrita fin decir fin decir
Incluso hoy en día, es raro encontrar este tipo de potencia en lenguajes de scripting de propósito general fuera de SQL .
Añadir soporte para AEOM en el Mac OS clásico fue un proceso difícil. Los desarrolladores de aplicaciones tenían que identificar sus objetos y escribir a mano el código para poder acceder a ellos. Esto normalmente tomaba la forma de código para devolver el "próximo" objeto de un tipo particular, lo que permitía a AppleScript iterarlos. Pero como el sistema operativo no contenía un modelo de objetos, este trabajo se dejaba enteramente en manos de los desarrolladores, muchos de los cuales no lo implementaron. Curiosamente, incluso el propio marco de aplicaciones de Apple , MacApp , no ofrecía un modelo de este tipo excepto para los objetos de la GUI que conocía, lo que una vez más obligaba al desarrollador a realizar la mayor parte del trabajo de crear scripts para los objetos que representaban los datos. En gran medida por estas razones, el soporte de AppleScript no estaba muy extendido.
Apple intentó resolver este problema con la introducción de varias "suites" de objetos, que representaban objetos y verbos estándar que se esperaba que fueran compatibles con distintos tipos de aplicaciones. Por ejemplo, se esperaba que todas las aplicaciones admitieran la "suite principal", y que cualquier aplicación que editara texto admitiera la "suite de texto". Al seleccionar un conjunto adecuado de suites, el desarrollador podía al menos reducir la carga de trabajo de planificar cómo exponer sus objetos. Sin embargo, como estos objetos generalmente no formaban parte del sistema en sí (con la excepción del editor TextEdit, que era muy limitado), la implementación real quedaba en manos del desarrollador.
Las aplicaciones desarrolladas en Cocoa , el sistema anteriormente conocido como OpenStep , ofrecen un entorno de ejecución de objetos enriquecido que puede consultarse desde cualquier otra aplicación. Esto hace que la implementación de AEOM sea considerablemente más sencilla, reduciendo drásticamente la cantidad de código necesario en la aplicación promedio. Además, la mayoría de las aplicaciones Cocoa se construyen principalmente a partir de objetos estándar de Cocoa, todos los cuales se actualizaron para ofrecer una capacidad de creación de scripts bastante amplia. Esto se extiende no solo a los objetos de la GUI como en MacApp, sino también a los objetos de datos dentro de ellos, incluidos texto, tablas y varios objetos de lista. Se utiliza un archivo de texto para mapear los nombres internos "similares a objetos" en versiones legibles para humanos y, en la mayoría de los casos, crear esto es todo lo que se necesita para agregar una capacidad de creación de scripts bastante sustancial a la mayoría de los programas.
Si bien las aplicaciones Cocoa no se basan en AEOM y a menudo utilizan objetos sutilmente diferentes de los objetos estándar definidos originalmente por Apple, las aplicaciones Cocoa generalmente son mucho más programables que sus contrapartes "clásicas"; de hecho, es poco común encontrar una aplicación Cocoa que no sea programable hasta cierto punto.
Scripting Bridge es un marco de trabajo de macOS que permite que las aplicaciones se comuniquen entre sí sin el uso de un lenguaje de script intermediario como AppleScript . Al igual que AppleScript, Scripting Bridge utiliza eventos de Apple para la comunicación entre aplicaciones . [1]
El puente de scripting se utiliza normalmente desde Objective-C , [1] pero se puede utilizar en otros lenguajes de programación a través de un puente Objective-C como MacRuby [2] y PyObjC .
{{citation}}
: Mantenimiento de CS1: falta la ubicación del editor ( enlace )En particular, consulte la Sección 2.3 “Apple Events” (páginas 9 a 13), aunque la historia y la importancia de Apple Events también se analizan en otras partes del documento.