Guides and Sample Code

Developer

Mac Automation Scripting Guide

On This Page

Using Handlers/Functions

Collections of script statements that can be invoked by name are referred to as handlers in AppleScript, functions or methods in JavaScript, and subroutines in some other languages. Throughout this document, these terms are used interchangeably.

Handlers are generally written to perform a task multiple times throughout a script, such as displaying an alert, writing text to a file, or creating an email message. Instead of inserting the same code over and over, you write it once and give it a name. You can name a handler whatever you like as long as the name contains no special characters, such as punctuation, or spaces, and isn’t a reserved language term. You then call, or evoke, a handler whenever necessary by referring to it by name. Each time you do, any code in the handler runs. Handlers can optionally be written to receive information as input for processing (parameters), and can return information as output (result or return value).

Handlers provide a way to organize your code by breaking it up into smaller, manageable, modular chunks. This can be useful when troubleshooting; you can narrow in on a single handler to resolve a problem, rather than sorting through a long, complex script. It also makes future script updates easier, as you can change behavior in one place to affect an entire script.

AppleScript Handlers

In AppleScript, a handler begins with the word on or to, followed by the handler name and its parameters, if any. It ends with the word end, followed by the handler name. AppleScript handlers can be written with positional, labeled, or interleaved parameters.

Listing 13-1 shows a simple one-line script that displays a hypothetical error message, which you might want to display numerous times as a script runs.

APPLESCRIPT

Open in Script Editor

Listing 13-1AppleScript: A simple script that displays an error message
  1. display dialog "The script encountered a problem."

In Listing 13-1, the code from Listing 13-1 has been converted to a handler named displayError, which has no parameters.

APPLESCRIPT

Open in Script Editor

Listing 13-2AppleScript: A simple handler that displays an error message
  1. on displayError()
  2. display dialog "The script encountered a problem."
  3. end displayError

Listing 13-3 shows a variation of the handler in Listing 13-1, which uses the to prefix instead of on. Either syntax is acceptable.

APPLESCRIPT

Open in Script Editor

Listing 13-3AppleScript: A variation of a simple handler that displays an error message
  1. to displayError()
  2. display dialog "The script encountered a problem."
  3. end displayError

You can now call the displayError handler any time you want to display an error, as shown in Listing 13-4.

APPLESCRIPT

Open in Script Editor

Listing 13-4AppleScript: Calling a simple handler to display an error message
  1. try
  2. -- Do something
  3. on error
  4. -- Notify the user that there's a problem
  5. displayError()
  6. end try
  7. try
  8. -- Do something else
  9. on error
  10. -- Notify the user that there's a problem
  11. displayError()
  12. end try

For detailed information about AppleScript handlers, see About Handlers and Handler Reference in AppleScript Language Guide.

AppleScript Handlers with Positional Parameters

Positional parameters are a series of comma-separated variables, contained within parentheses, following the handler name. In Listing 13-6, the displayError handler from Listing 13-1 has been updated to accept two positional parameters—an error message and a list of buttons to display.

APPLESCRIPT

Open in Script Editor

Listing 13-6AppleScript: A handler that displays a specified error message with custom buttons
  1. on displayError(theErrorMessage, theButtons)
  2. display dialog theErrorMessage buttons theButtons
  3. end displayError

To call the handler, refer to it by name and provide a value for each positional parameter, as shown in Listing 13-7. The order of these values should match the parameter positions in the handler definition.

APPLESCRIPT

Open in Script Editor

Listing 13-7AppleScript: Calling a handler to display a specified error message with custom buttons
  1. displayError("There's not enough available space. Would you like to continue?", {"Don't Continue", "Continue"})

For additional information about this style of handler, see Handlers with Positional Parameters in AppleScript Language Guide.

AppleScript Handlers with Interleaved Parameters

Interleaved parameters are a variation of positional parameters, in which the parameter name is split into pieces and interleaved with parameters using colons and spaces. Listing 13-8 shows how the handler from Listing 13-6 can be represented using interleaved parameters.

APPLESCRIPT

Open in Script Editor

Listing 13-8AppleScript: Example of a handler with interleaved parameters
  1. tell me to displayError:"There's not enough available space. Would you like to continue?" withButtons:{"Don't Continue", "Continue"}
  2. on displayError:theErrorMessage withButtons:theButtons
  3. display dialog theErrorMessage buttons theButtons
  4. end displayError:withButtons:

Interleaved parameters resemble Objective-C syntax. Therefore, they are typically used to call Objective-C methods in AppleScriptObjC scripts.

Objective-C to AppleScript Quick Translation Guide discusses interleaved parameter use in AppleScriptObjC scripts. For additional information about this style of handler, see Handlers with Interleaved Parameters in AppleScript Language Guide.

AppleScript Handlers with Labeled Parameters

AppleScript also supports labeled parameters, although this style is rarely used when defining custom handlers. Most often, it’s a style used for event handlers. See Event Handlers. Listing 13-9 shows how the displayError handler might appear if it were written using the labeled parameter style.

APPLESCRIPT

Open in Script Editor

Listing 13-9AppleScript: Example of a handler with labeled parameters
  1. display of "There's not enough available space. Would you like to continue?" over {"Don't Continue", "Continue"}
  2. to display of theErrorMessage over theButtons
  3. display dialog theErrorMessage buttons theButtons
  4. end display

For additional information about this style of handler, see Handlers with Labeled Parameters in AppleScript Language Guide.

JavaScript Functions

In JavaScript, a function name is preceded by the word function and followed by a list of parameters, if any. The function’s contents are contained within curly braces ({ ... }).

Listing 13-10 shows a simple script that displays a hypothetical error message.

JAVASCRIPT

Open in Script Editor

Listing 13-10JavaScript: A simple function that displays an error message
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. function displayError() {
  4. app.displayDialog("The script encountered a problem.")
  5. }

You can now call the displayError function any time you want to display an error, as shown in Listing 13-11.

JAVASCRIPT

Open in Script Editor

Listing 13-11JavaScript: Calling a simple function to display an error message
  1. try {
  2. // Do something
  3. } catch (error) {
  4. // Notify the user that there's a problem
  5. displayError()
  6. }
  7. try {
  8. // Do something else
  9. } catch (error) {
  10. // Notify the user that there's a problem
  11. displayError()
  12. }

Using Parameters

JavaScript functions are written with positional parameters, comma-separated variables, contained within parentheses, following the function name. In Listing 13-12, the displayError function from Listing 13-10 has been updated to accept two positional parameters—an error message and a list of buttons to display.

JAVASCRIPT

Open in Script Editor

Listing 13-12JavaScript: A function that displays a specified error message with custom buttons
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. function displayError(errorMessage, buttons) {
  4. app.displayDialog(errorMessage, {
  5. buttons: buttons
  6. })
  7. }

To call the function, refer to it by name and provide a value for each positional parameter, as shown in Listing 13-13. The order of these values should match the parameter positions in the function definition.

JAVASCRIPT

Open in Script Editor

Listing 13-13JavaScript: Calling a function to display a specified error message with custom buttons
  1. displayError("There's not enough available space. Would you like to continue?", ["Don't Continue", "Continue"])

Exiting Handlers and Returning a Result

Often, handlers are used to process information and produce a result for further processing. To enable this functionality, add the return command, followed by a value to provide, to the handler. In Listing 13-14 and Listing 13-15, the displayError handler returns a Boolean value, indicating whether processing should continue after an error has occurred.

APPLESCRIPT

Open in Script Editor

Listing 13-14AppleScript: Returning a value from a handler
  1. set shouldContinueProcessing to displayError("There's not enough available space. Would you like to continue?")
  2. if shouldContinueProcessing = true then
  3. -- Continue processing
  4. else
  5. -- Stop processing
  6. end if
  7. on displayError(theErrorMessage)
  8. set theResponse to display dialog theErrorMessage buttons {"Don't Continue", "Continue"} default button "Continue"
  9. set theButtonChoice to button returned of theResponse
  10. if theButtonChoice = "Continue" then
  11. return true
  12. else
  13. return false
  14. end if
  15. end displayError

JAVASCRIPT

Open in Script Editor

Listing 13-15JavaScript: Returning a value from a function
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. function displayError(errorMessage) {
  4. var response = app.displayDialog(errorMessage, {
  5. buttons: ["Don't Continue", "Continue"],
  6. defaultButton: "Continue"
  7. })
  8. var buttonChoice = response.buttonReturned
  9. if (buttonChoice == "Continue")
  10. return true
  11. else
  12. return false
  13. }
  14. var shouldContinueProcessing = displayError("There's not enough available space. Would you like to continue?")
  15. if (shouldContinueProcessing) {
  16. // Continue processing
  17. } else {
  18. // Stop processing
  19. }

Event Handlers

Some apps, including scripts themselves, can call handlers when certain events occur, such as when launched or quit. In Mail, you can set up a rule to look for incoming emails matching certain criteria. When a matching email is detected, Mail can call a handler in a specified script to process the email. Handlers like these are considered event handlers or command handlers.

Listing 13-16 shows an example of a Mail rule event handler. It receives any detected messages as input, and can loop through them to process them.

APPLESCRIPT

Open in Script Editor

Listing 13-16AppleScript: Example of a Mail rule event handler
  1. using terms from application "Mail"
  2. on perform mail action with messages theDetectedMessages for rule theRule
  3. tell application "Mail"
  4. set theMessageCount to count of theDetectedMessages
  5. repeat with a from 1 to theMessageCount
  6. set theCurrentMessage to item a of theDetectedMessages
  7. -- Process the message
  8. end repeat
  9. end tell
  10. end perform mail action with messages
  11. end using terms from

Script Event Handlers

As previously mentioned, scripts can contain event handlers too. These handlers run when certain events occur.

Run Handlers

The run event handler is called when a script runs. By default, any executable code at the top level of a script—that is, not contained within a handler or script object—is considered to be contained within an implicit run handler. See Listing 13-17 and Listing 13-18.

APPLESCRIPT

Open in Script Editor

Listing 13-17AppleScript: Example of an implicitly defined run handler
  1. display dialog "The script is running."

JAVASCRIPT

Open in Script Editor

Listing 13-18JavaScript: Example of an implicitly defined run function
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. app.displayDialog("The script is running.")

Optionally, the run handler can be explicitly defined. Listing 13-19 and Listing 13-20 produce the exact same behavior as Listing 13-17 and Listing 13-18.

APPLESCRIPT

Open in Script Editor

Listing 13-19AppleScript: Example of an explicitly defined run handler
  1. on run
  2. display dialog "The script is running."
  3. end run

JAVASCRIPT

Open in Script Editor

Listing 13-20JavaScript: Example of an explicitly defined run function
  1. function run() {
  2. var app = Application.currentApplication()
  3. app.includeStandardAdditions = true
  4. app.displayDialog("The script is running.")
  5. }

Quit Handlers

The quit event handler is optional, and is called when a script app quits. Use this as an opportunity to perform cleanup tasks, if necessary, such as removing temporary folders or logging progress. Listing 13-21 and Listing 13-22 demonstrate the use of a quit handler.

APPLESCRIPT

Open in Script Editor

Listing 13-21AppleScript: Example of a quit handler
  1. on quit
  2. display dialog "The script is quitting."
  3. end quit

JAVASCRIPT

Open in Script Editor

Listing 13-22JavaScript: Example of a quit function
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. function quit() {
  4. app.displayDialog("The script is quitting.")
  5. }

Open Handlers

The inclusion of an open handler or openDocuments method in a script app automatically makes the app drag-and-droppable. When launched in this way, the open handler receives a dropped list of files or folders as a direct parameter, as shown in Listing 13-23 and Listing 13-24.

APPLESCRIPT

Open in Script Editor

Listing 13-23AppleScript: Structure of an open handler
  1. on open theDroppedItems
  2. -- Process the dropped items here
  3. end open

JAVASCRIPT

Open in Script Editor

Listing 13-24JavaScript: Structure of an openDocuments function
  1. function openDocuments(droppedItems) {
  2. // Process the dropped items here
  3. }

For detailed information about using the open handler to create drop scripts, see Processing Dropped Files and Folders.

Idle Handlers

When saving a script, you can optionally save it as a stay-open application. See Figure 13-1. In a stay-open script app, the script stays open after the run handler completes, and an idle handler is called every 30 seconds. Use the idle handler to perform periodic processing tasks, such as checking a watched folder for new files to process. To change the duration between idle calls, return a new duration, in seconds, as the result of the idle handler. Listing 13-25 and Listing 13-26 demonstrate an idle handler that delays for five seconds between executions.

Figure 13-1Saving a stay-open script image: ../Art/scripteditor_savestayopenapp_2x.png

APPLESCRIPT

Open in Script Editor

Listing 13-25AppleScript: Example of an idle handler
  1. on idle
  2. display dialog "The script is idling."
  3. return 5
  4. end idle

JAVASCRIPT

Open in Script Editor

Listing 13-26JavaScript: Example of an idle function
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. function idle() {
  4. app.displayDialog("The script is idling.")
  5. return 5
  6. }

For information about using the idle handler for folder watching, see Watching Folders.