| Paradigm | Natural language programming, Scripting |
|---|---|
| Developer | Apple Inc. |
| First appeared | 1993; 23 years ago |
| Stable release |
2.7 / October 16, 2014; 2 years ago[1] |
| Typing discipline | Weak, dynamic |
| OS | System 7, Mac OS 8, Mac OS 9, macOS |
| License | Proprietary (parts available under APSL) |
| Filename extensions | .scpt, .scptd, .AppleScript |
| Website | developer |
| Influenced by | |
| Natural language, HyperCard | |
AppleScript is a scripting language created by Apple Inc. and built into the Classic Mac OS since System 7 and into all versions of macOS. The term "AppleScript" may refer to the scripting system itself, or to an individual script written in the AppleScript language.
AppleScript is primarily a scripting language developed by Apple to do Inter-Application Communication (IAC) using AppleEvents. AppleScript is related to, but different from, AppleEvents. AppleEvents is designed to exchange data between and control other applications in order to automate repetitive tasks. AppleScript has some limited processing abilities of its own, in addition to sending and receiving AppleEvents to applications. AppleScript can do basic calculations and complex text processing, and is extensible, allowing the use of scripting additions that add new functions to the language. Mainly, however, AppleScript relies on the functionality of applications and processes to handle complex tasks. As a structured command language, AppleScript can be compared to Unix shells, the Microsoft Windows Script Host, or IBM REXX in its functionality,[original research?] but it is unique from all three. Essential to its functionality is the fact that Macintosh applications publish "dictionaries" of addressable objects and operations.
AppleScript has some elements of object-oriented programming, particularly in the construction of script objects, and natural language programming tendencies in its syntax, but does not strictly conform to either category.
The AppleScript project was an attempt to consolidate a proliferation of scripting languages created and maintained by different groups and products at Apple. AppleScript was partly modeled on HyperCard's simple English language-based scripting language called HyperTalk, which could be used by novices to program a HyperCard stack. Apple engineers recognized that a similar, but more object-oriented scripting language could be designed to be used with any application, and the AppleScript project was born as a spin-off of a research effort to modernize the Macintosh as a whole and finally became part of System 7.
AppleScript was released in October 1993 as part of System 7.1.1 (System 7 Pro, the first major upgrade to System 7). QuarkXPress (ver. 3.2) was one of the first major software applications that supported AppleScript. This in turn led to AppleScript being widely adopted within the publishing and prepress world, often tying together complex workflows. This was a key factor in retaining the Macintosh's dominant position in publishing and prepress, even after QuarkXpress and other publishing applications were ported to Microsoft Windows.
After some uncertainty about the future of AppleScript on Apple's next generation OS, the move to Mac OS X (around 2002) and its Cocoa frameworks greatly increased the usefulness and flexibility of AppleScript. Cocoa applications allow application developers to implement basic scriptability for their apps with minimal effort, broadening the number of applications that are directly scriptable. At the same time, the shift to the Unix underpinnings and AppleScript's ability to run Unix commands directly allowed AppleScripts much greater control over the operating system itself. AppleScript Studio, released with Mac OS X 10.2 as part of Xcode, and later AppleScriptObjC framework, released in Mac OS X 10.6, allows users to build native Cocoa applications using AppleScript.
AppleScript is one component of macOS Automation technologies, along with Services, Automator, and Shell scripting.
AppleScript was designed to be used as an accessible end-user scripting language, offering users an intelligent mechanism to control applications, and to access and modify data and documents. AppleScript uses Apple Events: a set of standardized data formats that the Macintosh operating system uses to send information to applications. Apple Events allow a script to work with multiple applications simultaneously, passing data between them so that complex tasks can be accomplished without human interaction. For example, an AppleScript to create a simple web gallery might do the following:
For the user, hundreds or thousands of steps in multiple applications have been reduced to the single act of running the script, and the task is accomplished in much less time and with no possibility of random human error. A large complex script could be developed to run only once, while other scripts are used again and again.
An application's AppleScript elements are visible in the application's Scripting Dictionary (distributed as part of the application), which can be viewed in any script editor. Elements are generally grouped into suites, according to loose functional relationships between them. There are two basic kinds of elements present in any suite: Classes and Commands. Classes are scriptable objects - for example, a text editing application will almost certainly have classes for Windows, Documents, and Texts - and these classes will have properties that can be changed (window size, document background color, text font size, etc.), and may contain other classes (a window will contain one or more documents, a document will contain text, a text object will contain paragraphs and words and characters). Commands, by contrast, are commands that can be given to scriptable objects. The general format for a block of AppleScript is to tell a scriptable object to run a command.
All scriptable applications share a few basic commands and objects (usually called the Standard Suite) - commands to open, close or save a file, to print something, to quit, to set data to variables - as well as a basic application object that gives the scriptable properties of the application itself. Many applications have numerous suites capable of performing any task the application itself can perform. In exceptional cases, applications may support plugins which include their own scripting dictionaries.
AppleScript was designed with the ability to build scripts intuitively by recording user actions. When the AppleScript Editor is open and the Record button clicked, any user actions on the computer - in any application that supports AppleEvents and AppleScript recording - are converted to their equivalent AppleScript commands and placed in the script editor window. The resulting script can be saved and re-run to duplicate the original actions, or modified to be more generally useful.
Comments can be made multiple ways. If you need to make a small one-line comment, you can use 2 hyphens (-), or a number sign (#). Example:
--This is a one line comment #So is this!
If you need to have a rather long comment that takes up multiple lines, you would use parentheses with asterisks inside. Example:
(* This is a multiple line comment *)
In AppleScript, the traditional "Hello, world!" program could be written in many different forms:
display dialog "Hello, world!" -- a modal window with “OK” and “Cancel” buttons -- or display alert "Hello, world!" -- a modal window with a single “OK” button and an icon representing the app displaying the alert -- or say "Hello, world!" -- an audio message using a synthesized computer voice
AppleScript has several user interface options, including dialogs, alerts, and list of choices. (The character ¬, produced by typing option-return in the Script Editor, denotes continuation of a single statement across multiple lines.)
-- Dialog set dialogReply to display dialog "Dialog Text" ¬ default answer "Text Answer" ¬ hidden answer false ¬ buttons {"Skip", "Okay", "Cancel"} ¬ default button "Okay" ¬ cancel button "Skip" ¬ with title "Dialog Window Title" ¬ with icon note ¬ giving up after 15
-- Choose from list set chosenListItem to choose from list {"A", "B", "3"} ¬ with title "List Title" ¬ with prompt "Prompt Text" ¬ default items "B" ¬ OK button name "Looks Good!" ¬ cancel button name "Nope, try again" ¬ multiple selections allowed false ¬ with empty selection allowed
-- Alert set resultAlertReply to display alert "Alert Text" ¬ as warning ¬ buttons {"Skip", "Okay", "Cancel"} ¬ default button 2 ¬ cancel button 1 ¬ giving up after 2
Each user interaction method can return the values of buttons clicked, items chosen or text entered for further processing. For example:
display alert "Hello, world!" buttons {"Rudely decline", "Happily accept"} set theAnswer to button returned of the result if theAnswer is "Happily accept" then beep 5 else say "Piffle!" end if
Whereas AppleEvents are a way to send messages into applications, AppleScript is a particular language designed to send Apple Events. In keeping with the Mac OS tradition of ease-of-use, the AppleScript language is designed on the natural language metaphor, just as the graphical user interface is designed on the desktop metaphor. A well-written AppleScript should be clear enough to be read and understood by anyone, and easily edited. The language is based largely on HyperCard's HyperTalk language, extended to refer not only to the HyperCard world of cards and stacks, but also theoretically to any document. To this end, the AppleScript team introduced the AppleEvent Object Model (AEOM), which specifies the objects any particular application "knows".
The heart of the AppleScript language is the use of terms that act as nouns and verbs that can be combined. For example, rather than a different verb to print a page, document or range of pages (printPage, printDocument, printRange), AppleScript uses a single "print" verb which can be combined with an object, such as a page, a document or a range of pages.
print page 1 print document 2 print pages 1 thru 5 of document 2
Generally, AEOM defines a number of objects—like "document" or "paragraph"—and corresponding actions—like "cut" and "close". The system also defines ways to refer to properties of objects, so one can refer to the "third paragraph of the document 'Good Day'", or the "color of the last word of the front window". AEOM uses an application dictionary to associate the Apple Events with human-readable terms, allowing the translation back and forth between human-readable AppleScript and bytecode Apple Events. To discover what elements of a program are scriptable, dictionaries for supported applications may be viewed. (In the Xcode and Script Editor applications, this is under File → Open Dictionary.)
To designate which application is meant to be the target of such a message, AppleScript uses a "tell" construct:
tell application "Microsoft Word" quit end tell
Alternatively, the tell may be expressed in one line by using an infinitive:
tell application "Microsoft Word" to quit
For events in the "Core Suite" (activate, open, reopen, close, print, and quit), the application may be supplied as the direct object to transitive commands:
quit application "Microsoft Word"
The concept of an object hierarchy can be expressed using nested blocks:
tell application "QuarkXPress" tell document 1 tell page 2 tell text box 1 set word 5 to "Apple" end tell end tell end tell end tell
The concept of an object hierarchy can also be expressed using nested prepositional phrases:
pixel 7 of row 3 of TIFF image "my bitmap"
which in another programming language might be expressed as sequential method calls, like in this pseudocode:
getTIFF("my bitmap").getRow(3).getPixel(7);
AppleScript includes syntax for ordinal counting, "the first paragraph", as well as cardinal, "paragraph one". Likewise, the numbers themselves can be referred to as text or numerically, "five", "fifth" and "5" are all supported; they are synonyms in AppleScript. Also, the word "the" can legally be used anywhere in the script in order to enhance readability: it has no effect on the functionality of the script.
A failsafe calculator:
tell application "Finder" -- Set variables set the1 to text returned of (display dialog "1st" default answer "Number here" buttons {"Continue"} default button 1) set the2 to text returned of (display dialog "2nd" default answer "Number here" buttons {"Continue"} default button 1) try set the1 to the1 as integer set the2 to the2 as integer on error display dialog "You may only input numbers into a calculator." with title "ERROR" buttons {"OK"} default button 1 return end try -- Add? if the button returned of (display dialog "Add?" buttons {"No", "Yes"} default button 2) is "Yes" then set ans to (the1 + the2) display dialog ans with title "Answer" buttons {"OK"} default button 1 say ans -- Subtract? else if the button returned of (display dialog "Subtract?" buttons {"No", "Yes"} default button 2) is "Yes" then set ans to (the1 - the2) display dialog ans with title "Answer" buttons {"OK"} default button 1 say ans -- Multiply? else if the button returned of (display dialog "Multiply?" buttons {"No", "Yes"} default button 2) is "Yes" then set ans to (the1 * the2) display dialog ans with title "Answer" buttons {"OK"} default button 1 say ans -- Divide? else if the button returned of (display dialog "Divide?" buttons {"No", "Yes"} default button 2) is "Yes" then set ans to (the1 / the2) display dialog ans with title "Answer" buttons {"OK"} default button 1 say ans else delay 1 say "You haven't selected a function. The operation has cancelled." end if end tell
A simple username and password dialog box sequence. Here, the username is John and password is app123:
tell application "Finder" set passAns to "app123" set userAns to "John" if the text returned of (display dialog "Username" default answer "") is userAns then display dialog "Correct" buttons {"Continue"} default button 1 if the text returned of (display dialog "Username : John" & return & "Password" default answer "" buttons {"Continue"} default button 1) is passAns then display dialog "Access granted" buttons {"OK"} default button 1 else display dialog "Incorrect password" buttons {"OK"} default button 1 end if else display dialog "Incorrect username" buttons {"OK"} default button 1 end if end tell
Script editors provide a unified programing environment for AppleScripts, including tools for composing, validating, compiling, running, and debugging scripts. They also provide mechanisms for opening and viewing AppleScript dictionaries from scriptable applications, saving scripts in a number of formats (compiled script files, application packages, script bundles, and plain text files), and usually provide features such as syntax highlighting and prewritten code snippets.
AppleScripts can be run from a script editor, but it is usually more convenient to run scripts directly, without opening a script editor application. There are a number of options for doing so:
Many Apple applications, some third party applications, and some add-ons provide their own script menus. These may be activated in different ways, but all function in essentially the same manner.
AppleScript has a number of built-in classes (or data types), though of course an application can and most likely will define extra data types for its own purposes. The basic data classes that should be universally recognized are as follows:
Many AppleScript processes are managed by blocks of code, where a block begins with a command command and ends with an end command statement. The most important structures are described below.
AppleScript offers two kinds of conditionals.
-- Simple conditional if x < 1000 then set x to x + 1 -- Compound conditional if x is greater than 3 then -- commands else -- other commands end if
The repeat loop of AppleScript comes in several slightly different flavors. They all execute the block between repeat and end repeat lines a number of times. The looping can be prematurely stopped with command exit repeat.
Repeat forever.
repeat -- commands to be repeated end repeat
Repeat a given number of times.
repeat 10 times -- commands to be repeated end repeat
Conditional loops. The block inside repeat while loop executes as long as the condition evaluates to true. The condition is re-evaluated after each execution of the block. The repeat until loop is otherwise identical, but the block is executed as long as the condition evaluates to false.
set x to 5 repeat while x > 0 set x to x - 1 end repeat set x to 5 repeat until x ≤ 0 set x to x - 1 end repeat
Loop with a variable. When starting the loop, the variable is assigned to the start value. After each execution of the block, the optional step value is added to the variable. Step value defaults to 1.
-- repeat the block 2000 times, i gets all values from 1 to 2000 repeat with i from 1 to 2000 -- commands to be repeated end repeat -- repeat the block 4 times, i gets values 100, 75, 50 and 25 repeat with i from 100 to 25 by -25 -- commands to be repeated end repeat
Enumerate a list. On each iteration set the loopVariable to a new item in the given list
set total to 0 repeat with x in {1, 2, 3, 4, 5} set total to total + x end repeat
| Application Targeting | Error Handling |
|---|---|
-- Simple form tell application "Safari" to activate -- Compound tell application "MyApp" -- commands for app end tell |
try -- commands to be tested on error -- error commands end try |
One important variation on this block structure is in the form of on - end ... blocks that are used to define handlers (function-like subroutines). Handlers begin with on functionName() and ending with end functionName, and are not executed as part of the normal script flow unless called from somewhere in the script.
| Function handler | Folder actions block | Run handler |
|---|---|---|
on myFunction(parameters...) -- subroutine commands end myFunction |
on adding folder items to thisFolder after receiving theseItems -- commands to apply to the folder or items end adding folder items to |
on run -- commands end run |
Handlers can also be defined using "to" in place of "on" and can be written to accept labeled parameters, not enclosed in parens.
| Handler with Labeled Parameters | Handler Using "to" and Labeled Parameters |
|---|---|
on rock around the clock display dialog (clock as string) end rock -- called with: rock around the current date |
to check for yourNumber from bottom thru top if bottom ≤ yourNumber and yourNumber ≤ top then display dialog "Congratulations! You scored." end if end check --called with: check for 8 from 7 thru 10 |
There are four types of predefined handlers in AppleScript - run, open, idle, and quit - each of which is created in the same way as the run handler shown above.
on open theItems repeat with thisItem in theItems tell application "Finder" to update thisItem end repeat end open
When a script containing an "open handler' is saved as an applet, the applet becomes a droplet. A droplet can be identified in the Finder by its icon, which includes an arrow, indicating items can be dropped onto the icon. The droplet's open handler is executed when files or folders are dropped onto droplet's icon. References to the items dropped on the droplet's icon are passed to the droplet's script as the parameter of the open handler. A droplet can also be launched the same way as an ordinary applet, executing its run handler.
on idle --code to execute when the script's execution has completed return 60 -- number of seconds to pause before executing idle handler again end idle
An idle handler can be used in applets or droplets saved as stay-open applets, and is useful for scripts that watch for particular data or events. The length of the idle time is 30 seconds by default,[3] but can be changed by including a 'return x' statement at the end of the subroutine, where x is he number of seconds the system should wait before running the handler again.
on quit --commands to execute before the script quits continue quit -- required for the script to actually quit end quit
Script objects may be defined explicitly using the syntax:
script scriptName -- commands and handlers specific to the script end script
Script objects can use the same 'tell' structures that are used for application objects, and can be loaded from and saved to files. Runtime execution time can be reduced in some cases by using script objects.
set variable1 to 1 -- create an integer variable called variable1 set variable2 to "Hello" -- create a text variable called variable2 copy {17, "doubleday"} to variable3 -- create a list variable called variable3 set {variable4, variable5} to variable3 -- copy the list items of variable3 into separate variables variable4 and variable5 set variable6 to script myScript -- set a variable to an instance of a script
tell application "Finder" set x to my myHandler() -- or set x to myHandler() of me end tell on myHandler() --commands end myHandler
Using the same technique for scripting addition commands can reduce errors and improve performance.
tell application "Finder" set anyNumber to my (random number from 5 to 50) end tell
An important aspect of the AppleScript implementation is the Open Scripting Architecture (OSA).[4] Apple provides OSA for third-party scripting/automation products such as QuicKeys and UserLand Frontier, to function on an equal status with AppleScript. AppleScript was implemented as a scripting component, and the basic specs for interfacing such components to the OSA were public, allowing other developers to add their own scripting components to the system. Public client APIs for loading, saving and compiling scripts would work the same for all such components, which also meant that applets and droplets could hold scripts in any of those scripting languages.
Under macOS, the JavaScript OSA component remains the only serious OSA language alternative to AppleScript, though the Macintosh versions of Perl, Python, Ruby, and Tcl all support native means of working with AppleEvents without being OSA components.
One of the most interesting features of the OSA is "scripting additions", or OSAX for Open Scripting Architecture eXtension, which were based on HyperCard's External Commands. Scripting Additions are libraries that allow programmers to extend the function of AppleScript. Commands included as Scripting Additions are available system wide, and are not dependent on an application. macOS includes a collection of scripting additions referred to as Standard Additions, which extends the function of AppleScript with a variety of new commands, including user interaction dialogs, reading and writing files, file system commands, date functions, text and math operations.