Apple event

Last updated

Apple events are the message-based interprocess communication mechanism in Mac OS, first making an appearance in System 7 and supported by every version of the classic Mac OS since then and by macOS. Apple events describe "high-level" events such as "open document" or "print file", whereas earlier OSs had supported much more basic events, namely "click" and "keypress". Apple events form the basis of the Mac OS scripting system, the Open Scripting Architecture (the primary language of such being AppleScript).

Contents

The starting point is a dynamically-typed, extensible descriptor format called an AEDesc, which is just an OSType code specifying the data type, together with a block of type-dependent data. For instance, the OSType code inte indicates that the data was a four-byte signed integer in big-endian format.

Besides predefined type codes for various common simple types, there are two predefined structured descriptor types: an AERecord, which has data type reco (record), and AEList with type list (list or array). The internal structure of these contain recursively-nested AEDescs, while the AERecord also associates each element with a unique record field ID, which is an OSType. The Apple Event Manager provides API calls to construct these structures, as well as extract their contents and query the type of contents they hold.

The Apple Event Manager also supports coercions, which converts AEDescs from one data type to another. In addition to standard coercions, for instance between integer and real types, applications can install their own coercion handler callbacks, which handle conversions to and from custom data types.

An Apple event proper is an AERecord with fields that depended on the purpose of the event. In addition, it has attributes (which are distinct from record fields, which are now called the parameters of the event) from a set predefined by the Apple Event Manager. These specify what the event is supposed to do (through event class and event ID), the target address to which the event is to be sent (which could be a process on the local or a remote machine), and various other options for handling it. Remote machines initially had to be connected via AppleTalk, but Mac OS 9 added the option for connections via TCP/IP.

After sending an Apple event to its target process, the sending process can elect to receive a reply to an Apple event. This can contain various bits of information returned from the target about the processing of the original event, including an error code indicating success/failure, any information requested by the original event, and/or other appropriate information.

Apple events are the foundation of the AppleEvent Object Model, which in turn is the foundation of the OSA and AppleScript. As of 2016, the official implementation of the Apple Event Manager API is available in C and its descendants, including C++. Official bindings are also provided for Objective-C and Swift through the Cocoa API. Unofficial bindings also exist for other languages (with varying degrees of limitation), including Perl, UserTalk, Ruby and Python.

Object Model

The AppleEvent Object Model (AEOM) was a set of protocols built on top of AppleEvents by which applications running under classic Mac OS and macOS could control each other's functions. Applications that implemented some part of the AEOM were called scriptable because they could be controlled via AppleScript. Unfortunately, scriptability support remained patchy and inconsistent throughout the history of classic Mac OS.

The AEOM provided a syntactic layer under which any application could publish its internal objects, allowing those objects to be manipulated in a standardized way. Unlike other similar-sounding concepts such as ToolTalk, there was a clear, orthogonal distinction between nouns and verbs; thus, instead of providing separate commands for "close document" and "close window", there was a single "close" verb which could take references to "document" or "window" objects, or any other object that the application published.

The objects that an application made available through its AEOM support were arranged in a hierarchy. At the top was the application itself, referenced via a null object descriptor. Other objects were referenced by (recursively) specifying their parent object, together with other information identifying it as a child of that parent, all collected in an AERecord. An iterator was provided by parents to enumerate their children, or children of a certain class, allowing applications to address a set of elements. The system was generally similar to the Document Object Model used in XML, although with some differences in access patterns.

Each object could have elements and properties; elements were other objects, which might be created or deleted, while properties could not be created or deleted but had values which might be interrogated or changed. For instance, the application might have one or more window elements representing windows showing the contents of currently-open documents. These windows might have properties such as their title, position and size.

An application could define custom verbs for operating on its objects. The AEOM also specified various standard verbs which (it was hoped) applications would implement in a consistent fashion, such as open, close, create element, delete, set data, and get data. Each verb was defined as an AppleEvent of a specific type and class, together with particular parameters of particular types that were expected to be present. For instance, the "get data" event was the standard means for obtaining the value of a property: it took essentially one parameter, which was an object descriptor identifying the property to be queried. The value of that property would be returned in the reply event. The "set data" event took two parameters, the object descriptor for the property to set and the new value for the property; the reply event was only expected to return a success status or failure error code.

The entire AppleEvent architecture identifies things using four-byte OSType codes, studiously avoiding actual words or phrases in English (or any other language). Instead, the correspondence between internal AppleEvent codes and external natural-language descriptions is specified through the aete (AppleEvent Terminology Extension) resource the "extension" being to the standard terminology built into AppleScript itself. An application may provide multiple 'aete' resources for multiple languages, in keeping with the original multilingual design of AppleScript itself

For instance, consider the following AppleScript sequence controlling a fictional drawing application:

tellapplication"ScriptableDraw"setbackground colorofwindow"New Drawing"tobackground colorofwindow"Old Drawing"endtell

This actually involves the sending of two AppleEvents to the target application (and the receipt of their corresponding replies): first, a get-data event is sent to retrieve the background color property of the window identified by the name "Old Drawing"; then a set-data event is sent to apply the value returned as the background color property of the window named "New Drawing".

Since this sort of access pattern was typical, AppleScript made widespread use of the tell statement, which switched the context to the named object in a fashion similar to the with statement found in Visual Basic or Pascal. All commands after the tell to the corresponding end tell would be sent to the object named in the tell, instead of the default object, which was the current application.

Object descriptors allowed the identification of objects in various ways. The most interesting one was using a where-clause (which translated into AppleScript terminology as a filter expression). For instance, the AppleScript 1.0 SDK shipped with the source code for an example application called the Scriptable Text Editor, which would respond to scripts such as:

tellapplication"Scriptable Text Editor"tellwindow"Example Document"settextstyleofeverywordwhoselength>7toboldendtellendtell

Even today, it is rare to find this kind of power in general-purpose scripting languages outside of SQL.

Adding support for the AEOM in the classic Mac OS was a difficult process. Application developers had to identify their objects and hand-write code to allow them to be addressed. This typically took the form of code for returning the "next" object of a particular type, allowing AppleScript to iterate over them. But since the OS did not contain an object model, this work was left entirely to the developers, many of whom did not implement it. Oddly, even Apple's own application framework, MacApp, did not offer such a model except for the GUI objects it knew about, once again making the developer do most of the work of scripting the objects representing the data itself. Largely for these reasons, AppleScript support was not very widespread.

Apple did attempt to address this problem with the introduction of various object "suites", which represented standard objects and verbs that were expected to be supported by different types of applications. For instance, all applications were expected to support the "core suite", and any application editing text was expected to support the "text suite". By selecting a suitable set of suites, the developer could at least reduce the workload of planning how to expose their objects. Yet because these objects were generally not part of the system itself (with the exception of the severely limited TextEdit editor), the actual implementation was left to the developer.

Applications developed in Cocoa, the system formerly known as OpenStep, offer a rich object runtime that can be queried from any other application. This makes implementation of the AEOM considerably easier, dramatically reducing the amount of code needed in the average application. Additionally the majority of Cocoa applications are constructed primarily from Cocoa-standard objects, all of which were upgraded to offer fairly extensive scriptability. This extends not only to GUI objects as under MacApp, but also to data objects inside them, including text, tables and various list objects. A text file is used to map the internal "object-like" names onto human-readable versions, and in most cases creating this is all that is needed to add fairly substantial scriptability to most programs.

While Cocoa applications are not AEOM based, and often use subtly different objects than Apple's originally defined standard objects, Cocoa apps are generally much more scriptable than their "classic" counterparts—in fact, it is uncommon to find a Cocoa application that is not scriptable to some degree.

Scripting Bridge

The Scripting Bridge is a macOS framework which allows applications to communicate with each other without the use of an intermediary scripting language such as AppleScript. Like AppleScript, the Scripting Bridge uses Apple events for inter-application communication. [1]

The Scripting Bridge is typically used from Objective-C, [1] but can be used in other programming languages through an Objective-C bridge such as MacRuby [2] and PyObjC.

Further reading

Related Research Articles

Cocoa is Apple's native object-oriented application programming interface (API) for its desktop operating system macOS.

<span class="mw-page-title-main">GNUstep</span> Open source widget toolkit and application development tools

GNUstep is a free software implementation of the Cocoa Objective-C frameworks, widget toolkit, and application development tools for Unix-like operating systems and Microsoft Windows. It is part of the GNU Project.

Carbon was one of two primary C-based application programming interfaces (APIs) developed by Apple for the macOS operating system. Carbon provided a good degree of backward compatibility for programs that ran on Mac OS 8 and 9. Developers could use the Carbon APIs to port (“carbonize”) their “classic” Mac applications and software to the Mac OS X platform with little effort, compared to porting the app to the entirely different Cocoa system, which originated in OPENSTEP. With the release of macOS 10.15 Catalina, the Carbon API was officially discontinued and removed, leaving Cocoa as the sole primary API for developing macOS applications.

HyperTalk is a discontinued high-level, procedural programming language created in 1987 by Dan Winkler and used in conjunction with Apple Computer's HyperCard hypermedia program by Bill Atkinson. Because the main target audience of HyperTalk was beginning programmers, HyperTalk programmers were usually called "authors" and the process of writing programs was known as "scripting". HyperTalk scripts resembled written English and used a logical structure similar to that of the Pascal programming language.

AppleScript is a scripting language created by Apple Inc. that facilitates automated control over scriptable Mac applications. First introduced in System 7, it is currently included in all versions of macOS as part of a package of system automation tools. The term "AppleScript" may refer to the language itself, to an individual script written in the language, or, informally, to the macOS Open Scripting Architecture that underlies the language.

The resource fork is a fork or section of a file on Apple's classic Mac OS operating system, which was also carried over to the modern macOS for compatibility, used to store structured data along with the unstructured data stored within the data fork.

<span class="mw-page-title-main">Creator code</span>

A creator code is a mechanism introduced in the classic Mac OS to link a data file to the application program which created it. The similar type code held the file type, like "TEXT". Together, the type and creator indicated what application should be used to open a file, similar to the file extensions in other operating systems.

<span class="mw-page-title-main">ActionScript</span> Object-oriented programming language created for the Flash multimedia platform

ActionScript is an object-oriented programming language originally developed by Macromedia Inc.. It is influenced by HyperTalk, the scripting language for HyperCard. It is now an implementation of ECMAScript, though it originally arose as a sibling, both being influenced by HyperTalk. ActionScript code is usually converted to byte-code format by the compiler.

Object Pascal is an extension to the programming language Pascal that provides object-oriented programming (OOP) features such as classes and methods.

RubyCocoa is a macOS framework that provides a bridge between the Ruby and the Objective-C programming languages, allowing the user to manipulate Objective-C objects from Ruby, and vice versa. It makes it possible to write a Cocoa application completely in Ruby as well as to write an application that mixes Ruby and Objective-C code. An Apple project called MacRuby was under development to replace RubyCocoa in 2008. A proprietary spin-off called RubyMotion was subsequently released in 2012, available for iOS, macOS and Android.

MacApp is the object oriented application framework for Apple Computer's discontinued classic Mac OS. Released in 1985, it transitioned from Object Pascal to C++ in 1991's version 3.0 release, which offered support for much of System 7's new functionality. MacApp was used for a variety of major applications, including Adobe Photoshop and SoftPress Freeway. Microsoft's MFC and Borland's OWL were both based directly on MacApp concepts.

<span class="mw-page-title-main">AppKit</span> Graphical user interface toolkit

AppKit is a graphical user interface toolkit. It initially served as the UI framework for NeXTSTEP. Along with Foundation and Display PostScript, it became one of the core parts of the OpenStep specification of APIs. Later, AppKit and Foundation became part of Cocoa, the Objective-C API framework of macOS. GNUstep, GNU's implementation of the OpenStep/Cocoa API, also contains an implementation of the AppKit API.

Core Data is an object graph and persistence framework provided by Apple in the macOS and iOS operating systems. It was introduced in Mac OS X 10.4 Tiger and iOS with iPhone SDK 3.0. It allows data organized by the relational entity–attribute model to be serialized into XML, binary, or SQLite stores. The data can be manipulated using higher level objects representing entities and their relationships. Core Data manages the serialized version, providing object lifecycle and object graph management, including persistence. Core Data interfaces directly with SQLite, insulating the developer from the underlying SQL.

In the macOS, iOS, NeXTSTEP, and GNUstep programming frameworks, property list files are files that store serialized objects. Property list files use the filename extension .plist, and thus are often referred to as p-list files.

The Apple Developer Tools are a suite of software tools from Apple to aid in making software dynamic titles for the macOS and iOS platforms. The developer tools were formerly included on macOS install media, but are now exclusively distributed over the Internet. As of macOS 10.12, Xcode is available as a free download from the Mac App Store.

A Uniform Type Identifier (UTI) is a text string used on software provided by Apple Inc. to uniquely identify a given class or type of item. Apple provides built-in UTIs to identify common system objects – document or image file types, folders and application bundles, streaming data, clipping data, movie data – and allows third party developers to add their own UTIs for application-specific or proprietary uses. Support for UTIs was added in the Mac OS X 10.4 operating system, integrated into the Spotlight desktop search technology, which uses UTIs to categorize documents. One of the primary design goals of UTIs was to eliminate the ambiguities and problems associated with inferring a file's content from its MIME type, filename extension, or type or creator code.

Cocoa Touch is the application development environment for building software programs to run on iOS for the iPhone and iPod Touch, iPadOS for the iPad, watchOS for the Apple Watch, and tvOS for the Apple TV, from Apple Inc.

Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTSTEP operating system. Due to Apple macOS’s direct lineage from NeXTSTEP, Objective-C was the standard programming language used, supported, and promoted by Apple for developing macOS and iOS applications until the introduction of the Swift programming language in 2014.

In computer science, bridging describes systems that map the runtime behaviour of different programming languages so they can share common resources. They are often used to allow "foreign" languages to operate a host platform's native object libraries, translating data and state across the two sides of the bridge. Bridging contrasts with "embedding" systems that allow limited interaction through a black box mechanism, where state sharing is limited or non-existent.

Swift is a high-level general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. and the open-source community. First released in June 2014, Swift was developed as a replacement for Apple's earlier programming language Objective-C, as it had been largely unchanged since the early 1980s and lacked modern language features. Swift works with Apple's Cocoa and Cocoa Touch frameworks, and a key aspect of Swift's design was the ability to interoperate with the huge body of existing Objective-C code developed for Apple products over the previous decades. It was built with the open source LLVM compiler framework and has been included in Xcode since version 6, released in 2014. On Apple platforms, it uses the Objective-C runtime library, which allows C, Objective-C, C++ and Swift code to run within one program.

References

  1. 1 2 "Scripting Bridge". Apple Developer documentation. Retrieved 2023-02-04.
  2. Paul, Ryan (2011-09-27). "Tutorial: OS X automation with MacRuby and the Scripting Bridge". Ars Technica. Retrieved 2023-02-04.