События Apple — это механизм межпроцессного взаимодействия на основе сообщений в Mac OS , впервые появившийся в System 7 и поддерживаемый каждой версией классической Mac OS с тех пор и macOS . События Apple описывают «высокоуровневые» события, такие как «открытие документа» или «печать файла», тогда как более ранние ОС поддерживали гораздо более простые события, а именно «щелчок» и «нажатие клавиши». События Apple составляют основу системы сценариев Mac OS, Open Scripting Architecture (основным языком которой является AppleScript ).
Начальной точкой является динамически типизированный, расширяемый формат дескриптора, называемый AEDesc , который представляет собой просто код OSType , указывающий тип данных, вместе с блоком данных, зависящих от типа. Например, код OSType inte
указывает, что данные были четырехбайтовым целым числом со знаком в формате big-endian .
Помимо предопределенных кодов типов для различных общих простых типов, есть два предопределенных структурированных типа дескрипторов: AERecord , который имеет тип данных reco
(запись), и AEList с типом list
(список или массив). Внутренняя структура этих содержит рекурсивно вложенные AEDescs, в то время как AERecord также связывает каждый элемент с уникальным идентификатором поля записи, который является OSType. Apple Event Manager предоставляет вызовы API для построения этих структур, а также для извлечения их содержимого и запроса типа содержимого, которое они содержат.
Apple Event Manager также поддерживает приведения , которые преобразуют AEDescs из одного типа данных в другой. В дополнение к стандартным приведениям, например, между целыми и вещественными типами, приложения могут устанавливать собственные обработчики приведения , которые обрабатывают преобразования в пользовательские типы данных и из них.
Событие Apple — это AERecord с полями, которые зависят от цели события. Кроме того, у него есть атрибуты (отличные от полей записи, которые теперь называются параметрами события ) из набора, предопределенного диспетчером событий Apple. Они определяют, что должно делать событие (через класс события и идентификатор события ), целевой адрес, на который должно быть отправлено событие (это может быть процесс на локальной или удаленной машине), и различные другие параметры для его обработки. Удаленные машины изначально должны были подключаться через AppleTalk , но в Mac OS 9 была добавлена возможность для подключений через TCP/IP .
После отправки события Apple в целевой процесс отправляющий процесс может выбрать получение ответа на событие Apple. Он может содержать различные биты информации, возвращаемые целью об обработке исходного события, включая код ошибки, указывающий на успех/неудачу, любую информацию, запрошенную исходным событием, и/или другую соответствующую информацию.
События Apple являются основой AppleEvent Object Model , которая в свою очередь является основой OSA и AppleScript . По состоянию на 2016 год [обновлять]официальная реализация API Apple Event Manager доступна на языке C и его потомках, включая C++ . Официальные привязки также предоставляются для Objective-C и Swift через Cocoa API . Неофициальные привязки также существуют для других языков (с различной степенью ограничений), включая Perl , UserTalk , Ruby и Python .
AppleEvent Object Model ( AEOM ) — это набор протоколов, построенных поверх AppleEvents , с помощью которых приложения, работающие под классической Mac OS и macOS, могли управлять функциями друг друга. Приложения, реализующие некоторую часть AEOM, назывались скриптуемыми , поскольку ими можно было управлять с помощью AppleScript . К сожалению, поддержка скриптуемости оставалась неоднородной и непоследовательной на протяжении всей истории классической Mac OS.
AEOM предоставлял синтаксический слой, под которым любое приложение могло публиковать свои внутренние объекты, позволяя манипулировать этими объектами стандартизированным образом. В отличие от других схожих по звучанию концепций, таких как ToolTalk , существовало четкое, ортогональное различие между существительными и глаголами ; таким образом, вместо предоставления отдельных команд для «закрыть документ» и «закрыть окно», был один глагол «закрыть», который мог принимать ссылки на объекты «документ» или «окно» или любой другой объект, опубликованный приложением.
Объекты, которые приложение делало доступными через свою поддержку AEOM, были организованы в иерархию. Наверху находилось само приложение, на которое ссылались через дескриптор нулевого объекта. На другие объекты ссылались (рекурсивно) путем указания их родительского объекта вместе с другой информацией, идентифицирующей его как дочерний объект этого родителя, все это собиралось в AERecord . Родители предоставляли итератор для перечисления своих дочерних объектов или дочерних объектов определенного класса, что позволяло приложениям обращаться к набору элементов. Система в целом была похожа на Document Object Model , используемую в XML , хотя с некоторыми различиями в шаблонах доступа.
Каждый объект может иметь элементы и свойства ; элементы — это другие объекты, которые можно создавать или удалять, в то время как свойства нельзя создавать или удалять, но они имеют значения, которые можно опрашивать или изменять. Например, приложение может иметь один или несколько элементов окна, представляющих окна, показывающие содержимое открытых в данный момент документов. Эти окна могут иметь такие свойства, как заголовок, положение и размер.
Приложение могло определять пользовательские глаголы для работы со своими объектами. AEOM также указывал различные стандартные глаголы, которые (как надеялись) приложения будут реализовывать согласованным образом, например, открыть, закрыть, создать элемент, удалить, установить данные и получить данные. Каждый глагол был определен как AppleEvent определенного типа и класса вместе с определенными параметрами определенных типов, которые должны были присутствовать. Например, событие «получить данные» было стандартным средством для получения значения свойства: оно принимало по сути один параметр, который был дескриптором объекта, идентифицирующим запрашиваемое свойство. Значение этого свойства возвращалось в событии ответа. Событие «установить данные» принимало два параметра, дескриптор объекта для свойства, которое нужно установить, и новое значение для свойства; событие ответа должно было возвращать только статус успешного выполнения или код ошибки сбоя.
Вся архитектура AppleEvent идентифицирует вещи с помощью четырехбайтовых кодов OSType , старательно избегая реальных слов или фраз на английском (или любом другом языке). Вместо этого соответствие между внутренними кодами AppleEvent и внешними описаниями на естественном языке указывается через ресурс aete ( расширение терминологии AppleEvent ) — «расширение» относится к стандартной терминологии, встроенной в сам AppleScript. Приложение может предоставлять несколько ресурсов «aete» для нескольких языков, в соответствии с исходным многоязычным дизайном самого AppleScript
Например, рассмотрим следующую последовательность AppleScript, управляющую вымышленным приложением для рисования:
скажите приложению "ScriptableDraw" установить цвет фона окна " Новый рисунок" на цвет фона окна "Старый рисунок " end tell
Фактически это включает отправку двух событий AppleEvents целевому приложению (и получение соответствующих ответов): сначала отправляется событие get-data для получения свойства цвета фона окна, идентифицированного по имени «Old Drawing»; затем отправляется событие set-data для применения возвращенного значения в качестве свойства цвета фона окна, названного «New Drawing».
Поскольку этот тип шаблона доступа был типичным, AppleScript широко использовал оператор tell
, который переключал контекст на именованный объект способом, похожим на with
оператор, встречающийся в Visual Basic или Pascal . Все команды после tell
to the according end tell
будут отправлены объекту, названному в tell
, вместо объекта по умолчанию, которым было текущее приложение.
Дескрипторы объектов позволяли идентифицировать объекты различными способами. Самым интересным было использование where-clause (что в терминологии AppleScript переводится как выражение фильтра ). Например, AppleScript 1.0 SDK поставлялся с исходным кодом для примера приложения под названием Scriptable Text Editor, который отвечал на такие скрипты, как:
скажите приложению "Scriptable Text Editor" скажите окну "Example Document" установите стиль текста для каждого слова , длина которого > 7 , на жирный end tell end tell
Даже сегодня редко можно встретить такую мощь в скриптовых языках общего назначения за пределами SQL .
Добавление поддержки AEOM в классическую Mac OS было сложным процессом. Разработчикам приложений приходилось идентифицировать свои объекты и вручную писать код, чтобы к ним можно было обращаться. Обычно это принимало форму кода для возврата «следующего» объекта определенного типа, позволяя AppleScript перебирать их. Но поскольку ОС не содержала объектной модели, эта работа была полностью оставлена разработчикам, многие из которых не реализовали ее. Как ни странно, даже собственный фреймворк приложений Apple , MacApp , не предлагал такой модели, за исключением известных ему объектов GUI , что снова заставляло разработчика выполнять большую часть работы по написанию скриптов для объектов, представляющих сами данные. Во многом по этим причинам поддержка AppleScript не была широко распространена.
Apple попыталась решить эту проблему, введя различные объектные «наборы», которые представляли собой стандартные объекты и глаголы, которые, как ожидалось, должны были поддерживаться различными типами приложений. Например, все приложения должны были поддерживать «основной набор», а любое приложение, редактирующее текст, должно было поддерживать «текстовый набор». Выбрав подходящий набор наборов, разработчик мог, по крайней мере, уменьшить объем работы по планированию того, как выставлять свои объекты. Однако, поскольку эти объекты, как правило, не были частью самой системы (за исключением сильно ограниченного редактора TextEdit), фактическая реализация была оставлена разработчику.
Приложения, разработанные в Cocoa , системе, ранее известной как OpenStep , предлагают богатую среду выполнения объектов, которая может быть запрошена из любого другого приложения. Это значительно упрощает реализацию AEOM, значительно сокращая объем кода, необходимого для среднего приложения. Кроме того, большинство приложений Cocoa построены в основном из стандартных объектов Cocoa, все из которых были обновлены для предоставления довольно обширной возможности написания сценариев. Это распространяется не только на объекты GUI, как в MacApp, но и на объекты данных внутри них, включая текст, таблицы и различные объекты списков. Текстовый файл используется для сопоставления внутренних «объектоподобных» имен с человекочитаемыми версиями, и в большинстве случаев его создание — это все, что нужно для добавления довольно существенной возможности написания сценариев большинству программ.
Хотя приложения Cocoa не основаны на AEOM и часто используют объекты, немного отличающиеся от изначально определенных стандартных объектов Apple, приложения Cocoa, как правило, гораздо более поддаются написанию скриптов, чем их «классические» аналоги. Фактически, редко можно встретить приложение Cocoa, которое в той или иной степени не поддается написанию скриптов.
Scripting Bridge — это фреймворк macOS, который позволяет приложениям взаимодействовать друг с другом без использования промежуточного языка сценариев, такого как AppleScript . Как и AppleScript, Scripting Bridge использует события Apple для взаимодействия между приложениями . [1]
Scripting Bridge обычно используется в Objective-C [ 1], но может использоваться и в других языках программирования через мост Objective-C, например MacRuby [2] и PyObjC .
{{citation}}
: CS1 maint: отсутствует местоположение издателя ( ссылка ). В частности, см. раздел 2.3 «События Apple» (стр. 9–13), хотя история и важность событий Apple также обсуждаются в другом месте статьи.