Appleイベントは、 Mac OSにおけるメッセージベースのプロセス間通信メカニズムであり、 System 7で初めて登場し、それ以降のすべてのクラシックMac OSバージョンとmacOSでサポートされています。Appleイベントは、「ドキュメントを開く」や「ファイルを印刷する」といった「高レベル」のイベントを記述しますが、以前のOSでは「クリック」や「キーを押す」といった、より基本的なイベントがサポートされていました。Appleイベントは、Mac OSのスクリプトシステムであるOpen Scripting Architecture(その主要言語はAppleScript)の基盤となっています。
出発点となるのは、動的に型付けされ拡張可能な記述子フォーマットであるAEDescです。これは、データ型を指定するOSTypeコードと、型に依存するデータのブロックから構成されます。例えば、OSTypeコードは、データがビッグエンディアンinte形式の4バイト符号付き整数であることを示しています。
様々な一般的な単純型に対応する定義済み型コードに加え、定義済みの構造化記述子型が2種類あります。1つはデータ型(レコード)を持つAERecord 、もう1つは型(リストまたは配列)を持つAEListです。これらの内部構造は再帰的にネストされたAEDescで構成されており、AERecordは各要素を一意のレコードフィールドID(OSType)に関連付けています。Apple Event Managerは、これらの構造を構築したり、その内容を抽出したり、保持する内容の型を照会したりするためのAPI呼び出しを提供します。recolist
Apple Event Managerは、 AEDescをあるデータ型から別のデータ型に変換する型変換もサポートしています。整数型と実数型間の変換など、標準的な型変換に加えて、アプリケーションは独自の型変換ハンドラコールバックをインストールして、カスタムデータ型との変換を処理することができます。
本来のAppleイベントは、イベントの目的に応じてフィールドが異なる AERecord です。さらに、 Apple イベントマネージャによって事前に定義された属性(レコード フィールドとは異なり、現在はイベントのパラメータと呼ばれています) を持ちます。これらの属性は、イベントが実行すべき処理 (イベント クラスとイベント IDによって)、イベントの送信先アドレス (ローカル マシンまたはリモート マシンのプロセス)、およびイベントを処理するためのさまざまなオプションを指定します。当初、リモート マシンはAppleTalkを介して接続する必要がありましたが、Mac OS 9でTCP/IPを介して接続するオプションが追加されました。
送信プロセスは、Appleイベントをターゲットプロセスに送信した後、Appleイベントに対する応答を受信するかどうかを選択できます。この応答には、元のイベントの処理に関するターゲットからのさまざまな情報が含まれる可能性があり、これには、成功/失敗を示すエラーコード、元のイベントで要求された情報、およびその他の適切な情報が含まれます。
AppleイベントはAppleEventオブジェクトモデルの基盤であり、それがOSAとAppleScriptの基盤となっている。2016年現在Apple Event Manager API の公式実装は、Cおよびその派生言語 ( C++を含む) で利用可能です。また、Cocoa APIを介してObjective-CおよびSwift用の公式バインディングも提供されています。さらに、 Perl、UserTalk、Ruby、Pythonなど、他の言語用の非公式バインディングも存在します (ただし、機能に制限があります) 。
AppleEvent Object Model(AEOM )は、 AppleEventを基盤としたプロトコル群であり、従来のMac OSおよびmacOS上で動作するアプリケーションが互いの機能を制御できるように設計されていました。AEOMの一部を実装したアプリケーションは、AppleScriptを介して制御できるため、スクリプト対応アプリケーションと呼ばれていました。しかし残念ながら、スクリプト対応のサポートは、従来のMac OSの歴史を通じて、断片的で一貫性に欠ける状態が続いていました。
AEOMは、あらゆるアプリケーションが内部オブジェクトを公開できる構文レイヤーを提供し、それらのオブジェクトを標準化された方法で操作できるようにしました。ToolTalkなどの類似した概念とは異なり、名詞と動詞は明確に区別されていました。そのため、「ドキュメントを閉じる」と「ウィンドウを閉じる」に別々のコマンドを用意するのではなく、「閉じる」という単一の動詞があり、これは「ドキュメント」オブジェクトや「ウィンドウ」オブジェクト、あるいはアプリケーションが公開するその他のオブジェクトへの参照を受け取ることができました。
アプリケーションがAEOMサポートを通じて提供するオブジェクトは階層構造で配置されていました。最上位にはアプリケーション自体があり、ヌルオブジェクト記述子を介して参照されました。他のオブジェクトは、親オブジェクトと、その親の子であることを識別するその他の情報(すべてAERecordに収集される)を(再帰的に)指定することで参照されました。親オブジェクトは、子オブジェクト、または特定のクラスの子オブジェクトを列挙するためのイテレータを提供し、アプリケーションが要素のセットにアクセスできるようにしました。このシステムは、アクセスパターンに若干の違いはあるものの、XMLで使用されるドキュメントオブジェクトモデルと概ね類似していました。
各オブジェクトは要素とプロパティを持つことができます。要素は作成または削除可能な他のオブジェクトであり、プロパティは作成または削除できませんが、照会または変更可能な値を持ちます。たとえば、アプリケーションには、現在開いているドキュメントの内容を表示するウィンドウを表すウィンドウ要素が1つ以上存在する場合があります。これらのウィンドウには、タイトル、位置、サイズなどのプロパティが存在する可能性があります。
アプリケーションは、オブジェクトを操作するためのカスタム動詞を定義できます。AEOMでは、アプリケーションが一貫した方法で実装することが期待されるさまざまな標準動詞も規定されていました。たとえば、open、close、create element、delete、set data、get dataなどです。各動詞は、特定のタイプとクラスのAppleEventとして定義され、特定のタイプの特定のパラメータが存在することが想定されていました。たとえば、「get data」イベントは、プロパティの値を取得するための標準的な手段でした。このイベントは基本的に1つのパラメータを受け取ります。これは、クエリ対象のプロパティを識別するオブジェクト記述子です。そのプロパティの値は、応答イベントで返されます。「set data」イベントは、設定するプロパティのオブジェクト記述子とプロパティの新しい値の2つのパラメータを受け取ります。応答イベントは、成功ステータスまたは失敗エラーコードのみを返すことが想定されていました。
AppleEventアーキテクチャ全体は、4バイトのOSTypeコードを使用してオブジェクトを識別し、英語(またはその他の言語)の実際の単語やフレーズを意図的に避けています。代わりに、内部のAppleEventコードと外部の自然言語による記述との対応関係は、aete ( AppleEvent Terminology Extension)リソース によって指定されます。この「拡張」は、AppleScript自体に組み込まれた標準用語に対するものです。アプリケーションは、AppleScript自体の本来の多言語設計に従って、複数の言語に対応する複数の「aete」リソースを提供できます。
例えば、架空の描画アプリケーションを制御する以下のAppleScriptシーケンスを考えてみましょう。
アプリケーション「ScriptableDraw」に、ウィンドウ「New Drawing」の背景色をウィンドウ「Old Drawing」の背景色に設定するように指示する。実際には、これはターゲットアプリケーションに 2 つの AppleEvent を送信し(そしてそれに対応する応答を受信する)ことを含みます。まず、get-data イベントを送信して、「Old Drawing」という名前のウィンドウの背景色プロパティを取得します。次に、set-data イベントを送信して、返された値を「New Drawing」という名前のウィンドウの背景色プロパティとして適用します。
このようなアクセスパターンが一般的であったため、AppleScript では、 Visual BasicやPascalのステートメントtellと同様の方法でコンテキストを指定されたオブジェクトに切り替えるステートメントが広く使用されました。対応するオブジェクトへの以降のすべてのコマンドは、デフォルトのオブジェクト (現在のアプリケーション) ではなく、で指定されたオブジェクトに送信されます。withtellend telltell
オブジェクト記述子によって、さまざまな方法でオブジェクトを識別することが可能になりました。最も興味深い方法は、where句(AppleScriptの用語ではフィルタ式)を使用することでした。例えば、AppleScript 1.0 SDKには、Scriptable Text Editorというサンプルアプリケーションのソースコードが同梱されており、次のようなスクリプトに応答しました。
tell application "Scriptable Text Editor" tell window "Example Document" set text style of every word whose length > 7 to bold to bold end tell end tell今日でも、 SQL以外の汎用スクリプト言語で、これほどの強力な機能を持つものは稀である。
従来の Mac OSで AEOM のサポートを追加するのは困難な作業でした。アプリケーション開発者は、オブジェクトを識別し、それらを参照できるようにコードを手書きする必要がありました。これは通常、特定の型の「次の」オブジェクトを返すコードの形をとり、AppleScript がそれらを反復処理できるようにしました。しかし、OS にはオブジェクト モデルが含まれていなかったため、この作業はすべて開発者に委ねられ、多くの開発者はそれを実装しませんでした。奇妙なことに、Apple 自身のアプリケーション フレームワークであるMacAppでさえ、認識しているGUIオブジェクトを除いて、そのようなモデルを提供しておらず、やはり開発者がデータ自体を表すオブジェクトのスクリプト作成作業の大部分を行う必要がありました。主にこれらの理由から、AppleScript のサポートはあまり普及しませんでした。
Appleはこの問題に対処するため、さまざまなアプリケーションでサポートされることが期待される標準的なオブジェクトと動詞を表す、さまざまなオブジェクト「スイート」を導入しました。たとえば、すべてのアプリケーションは「コアスイート」をサポートすることが期待され、テキストを編集するアプリケーションはすべて「テキストスイート」をサポートすることが期待されました。適切なスイートのセットを選択することで、開発者は少なくともオブジェクトの公開方法を計画する作業量を減らすことができました。しかし、これらのオブジェクトは一般的にシステム自体の一部ではなかったため(非常に機能が制限されたTextEditエディタを除く)、実際の実装は開発者に委ねられました。
かつてOpenStepとして知られていたCocoaで開発されたアプリケーションは、他のアプリケーションからクエリ可能な豊富なオブジェクトランタイムを提供します。これにより、AEOMの実装が大幅に容易になり、平均的なアプリケーションに必要なコード量が劇的に削減されます。さらに、Cocoaアプリケーションの大部分は主にCocoa標準オブジェクトで構成されており、それらはすべてかなり広範なスクリプト機能を提供するようにアップグレードされています。これは、MacAppのようにGUIオブジェクトだけでなく、テキスト、テーブル、さまざまなリストオブジェクトなど、GUIオブジェクト内のデータオブジェクトにも適用されます。テキストファイルを使用して、内部の「オブジェクトのような」名前を人間が読みやすいバージョンにマッピングします。ほとんどの場合、このファイルを作成するだけで、ほとんどのプログラムにかなり高度なスクリプト機能を追加できます。
CocoaアプリケーションはAEOMベースではなく、Appleが当初定義した標準オブジェクトとは微妙に異なるオブジェクトを使用することが多いものの、一般的にCocoaアプリケーションは「クラシック」アプリケーションよりもはるかにスクリプト化しやすい。実際、ある程度スクリプト化できないCocoaアプリケーションは稀である。
Scripting Bridge は、 AppleScriptなどの中間スクリプト言語を使用せずにアプリケーション同士が通信できるようにする macOS フレームワークです。AppleScript と同様に、Scripting Bridge はアプリケーション間の通信に Apple イベントを使用します。[ 1 ]
スクリプティングブリッジは通常Objective-Cから使用されますが[ 1 ]、MacRuby [ 2 ]やPyObjCなどのObjective-Cブリッジを介して他のプログラミング言語でも使用できます。
{{citation}}: CS1 maint: 発行元が見つかりません (リンク)。特に、セクション 2.3「Apple Events」(9~13 ページ)を参照してください。ただし、Apple Events の歴史と重要性については、この論文の他の箇所でも説明されています。