Whereas Automator lets you construct a workflow visually by dragging and dropping actions into a list, AppleScript is a scripting language—a type of simplified programming language that runs only in a specific environment (in this case, macOS). That means AppleScripts can run only on a Mac, and because your Mac must interpret the commands in the script as it runs, an AppleScript won’t have the high performance of a conventional Mac app. Even so, AppleScripts can look and act like ordinary Mac apps. You may already be using some apps that were written in AppleScript without even realizing it!
AppleScript has been around since way back in 1993, and it’s become popular among people who like to tinker but wouldn’t consider themselves programmers, because it’s built into macOS and is a lot easier to work with than a big, complicated language like Swift or Objective-C. AppleScript is often referred to as “English-like,” which is a generous description at best, but if you don’t know much about programming, you can probably make more sense of AppleScript code than, say, Java.
In a moment, I’ll give you some examples of what you can do with AppleScript (see Learn What AppleScript Can Do). But first—before I lose the attention of people who think programming is Just Too Scary—I’m going to show you how to write a complete AppleScript program with exactly one English word. Here we go:
/Applications/Utilities
.beep
(Figure 34). Your script is now complete!
Two things should happen:
beep
changed its appearance from a purple, monospaced font to a bold, blue, proportional font. That’s because when you try to run an AppleScript, the script editor first compiles it, a process that checks to make sure it’s properly written. If it is, it formats the entire script in an easier-to-read fashion (which will be more apparent with a longer script).Now that you’ve written and run an AppleScript, you can follow the same steps to run scripts other people have written—simply type (or copy and paste) the scripts into AppleScript Editor and click the Run button. We’ll come back to this idea in a bit, but for now, I merely want to point out that using AppleScript can be as simple as that.
The simplest way to think about what AppleScript can do is that it provides an alternative means of performing common actions in macOS and in many apps. For example, you can open or quit an app with a menu command or the keyboard; AppleScript can also open or quit an app as part of a script. You can rename a file in the Finder; an AppleScript can do that too. You can open a word processor, search for a certain word, highlight the entire paragraph it appears in, make it bold, copy it, switch to another app, and paste it—or let AppleScript do all that for you with one click.
It’s that last type of activity—combining strings of actions that involve multiple apps—where AppleScript especially shines. AppleScript is also good at repetitive tasks (say, renaming dozens of files or fetching a long list of items from one place and copying them to another place) that would otherwise be tedious. And it gives you access to features on your Mac that aren’t normally exposed. For example, you just wrote a script that plays a beep, and although that happens when there’s an error, there’s no button or menu command that lets you manually trigger a beep. (AppleScript can trigger lots of actions that are far more interesting and useful than a beep!)
More importantly, an AppleScript can include logic that enables it to make decisions as it runs—either on its own, or with your input. It can use programming constructs such as variables, if-then conditions, and loops, and it can tie into numerous other automation tools (such as TextExpander, LaunchBar, and Keyboard Maestro).
Fine, you may say, but what exactly can AppleScript do?
Well, if you want to know every built-in command and option, with detailed background and examples, check out Apple’s massive Introduction to AppleScript Language Guide. It’s written mainly for developers, but it’s reasonably clear, and well worth consulting.
But that tells you only about AppleScript. To find out what you can do with AppleScript in a particular app, you’ll need to look elsewhere.
Every app that supports AppleScript, including the Finder, contains a dictionary of all the nouns and verbs AppleScript can use to control it. For example, the Calendar app’s dictionary contains verbs like create calendar
and switch view
; and nouns like calendar
, sound alarm
, attendee
, and event
. To see what’s in any app’s dictionary, you can either choose File > Open Dictionary in Script Editor, select an app, and click Choose, or drag an individual app’s icon from the Applications folder onto the Script Editor icon. Either way, you’ll see something like Figure 35. Look through the terms and read some of the definitions to see what sorts of things AppleScript can do in that app.
Unfortunately, not all apps support AppleScript, and of those that do, some of them have rather meager dictionaries (meaning you can’t do very much with them). But there are enough deeply scriptable apps out there to enable you to accomplish a great deal with AppleScript.
I could fill many pages with examples of tasks an AppleScript could perform, but here are just a few:
I’ll give even more examples as the chapter goes on.
As you’ve seen, a line of AppleScript code can be as simple as a single word. But they’re usually a bit more elaborate than that. Although even teaching the rudiments of the AppleScript language would require many pages, I wanted to give you at least a few pieces of background information to start your explorations in the right direction and help you understand the examples ahead. (If you’re impatient, you can jump right to Find and Run Example AppleScripts, and then check back here later for some of the details.) Later on, in Learn More about AppleScript, I’ll tell you where you can get top-to-bottom instruction in scripting with AppleScript.
As you’ll notice in the examples ahead, most scripts start with tell application "
App Name
"
on a line by itself, and conclude with an end tell
line, with everything else indented in between. These are examples of tell blocks, a ubiquitous construction in AppleScript. With a handful of exceptions (that is, commands interpreted by AppleScript itself rather than sent to an app), nearly everything you do in AppleScript involves telling some object (an app, a window, a paragraph) to do something. So you must always pay attention to which object you’re directing the current command, or set of commands to.
Tell blocks can be nested explicitly, in order to refer to an object that’s contained inside another object:
Or they can be combined like so:
tell front window of application "MyApp" to do something
Either way, if something isn’t working the way you expect, the first thing you should ask yourself is whether you’re telling the right entity to do something.
In AppleScript, each command normally goes on its own line. Instead of using a semicolon (;
) to indicate the end of a command, as some programming languages do, AppleScript looks for a return character.
Sometimes you’ll have a long AppleScript command that can’t fit on a single line. That’s no problem; word wrap works in Script Editor just as in any word processor. However, until you compile or run a script with a long line, you might find this automatically wrapped code hard to read. And, on Web sites and in books like this one, it can sometimes be hard to tell when you’re looking at a single AppleScript command that happens to span multiple lines, and when you’re looking at separate lines.
To address these problems, Script Editor lets you press Option-Return to insert a line continuation character (¬
), which is the script equivalent of a soft return. It means the line breaks at that point and the remainder of that command is indented underneath when the script is compiled or run, but the ¬
character itself is ignored (along with any leading or trailing spaces or tabs), and AppleScript treats the entire command as being on one line.
So this, for example, would be treated as one long line:
Like all programming and scripting languages, AppleScript supports variables of several kinds. In most cases, you don’t need to go through an extra step of declaring a variable to tell AppleScript what type of data it will store, because as long as you assign a value to a variable the first time you use it, AppleScript figures out what its type is automatically. To set a variable, you use the set
command, like so:
set someWord to "peaches"
That makes a variable of type string, since what you set it to was a string. You can also make an integer (set someNum to 12 + 34
), a boolean (set isIt to true
), a list (set theItems to {"cube", "sphere", "wedge"}
), and numerous other classes.
How do you later retrieve the value of a variable? Simple: you use the get
command, as in:
get someWord
If you happen to be running your script in Script Editor and it ends with a get
command, the Results area at the bottom of the window shows the variable’s current value. You an also display the value of a variable to the user (see Display Dialog, next), pass it to another part of your script, alter it, and so on.
Sometimes you’ll want to inform yourself, or whoever’s running your script, about its results, ask a question, or simply display the current value of a variable for the purpose of debugging or troubleshooting. For all these purposes and more, you’ll want to become good friends with the display dialog
command, which produces a simple dialog with customizable buttons (Cancel and OK by default), the text of your choice, and an optional text entry field.
Here are some common variants—try mixing and matching these to get different results:
display dialog "Hi there"
You can use an if/then statement (or if/then/else) to execute one or more commands only if a certain condition is true. Although there are multiple ways to format these, the most common ones look like these:
(Note that you must include the word then
at the end of the if
line; if you don’t, AppleScript will add it for you.)
To put a note to yourself or other people within a script that won’t be executed, put two hyphens (--
) in front of it, like so:
If your comment runs longer than a line, you can instead surround it with (*
and *)
, like this:
(* Wow, there’s so much to say about this excellent script. Where can I even begin. Well, let’s start at the beginning. Once upon a time… *)
There’s so much more to AppleScript, even under the “Basic” heading: properties, loops, references, indexes, arrays, handlers, and much more. As I said, I’ll point you to resources that can teach you this stuff. For our purposes, I wanted to make sure you could decode at least a bit of what’s going on in our example scripts, to which I now turn.
Here are some simple scripts to try. To use one, copy and paste (or retype) it into Script Editor and click the Run button.
A quick Web search should turn up thousands of AppleScripts that you can use—and I refer you to some additional sources ahead, in Learn More about AppleScript.
You can also find a bunch of sample scripts already on your Mac, in the /Library/Scripts
folder. You’ll notice that those scripts—and perhaps many of those you find online—aren’t just text; they’re AppleScript files. One way to use any of these is to double-click the file (which opens it in Script Editor) and then click the Run button. (For scripts located in /Library/Scripts
, you’ll be prompted to click a Duplicate button before your script runs so that changes can be saved.) But that’s not the only way!
Another way to access an AppleScript saved as a file is to choose its name from the AppleScript menu (Figure 40). Don’t see it? Open Script Editor, go to Script Editor > Preferences > General, and select the Show Script Menu in Menu Bar checkbox. By default, that shows all the scripts in /Library/Scripts
as well as ~/Library/Scripts
, so you can add to the menu by placing your scripts in one of those folders (or a subfolder).
To save any of your own scripts (including those you created using the sample code just previously) as files, choose File > Save, choose a name and location, and leave the File Format pop-up menu set to its default choice of Script. Then click Save.
One of the easiest ways to learn AppleScript is to start with a script that someone else has written, make a modification or two, and see what happens. If you like the results, make further changes, add a few new lines, or combine portions of multiple scripts. Once you have some experience fiddling with other people’s code, you’ll feel more comfortable creating scripts of your own from scratch.
You might start, for example, with the Resize the frontmost Safari window script from a few pages back. Try replacing Safari
with the name of another app. Or, try changing this line:
set bounds of front window to {0, 0, 1000, 600}
Those numbers refer, respectively, to the window’s distance (in pixels) from the left edge of the screen; distance from the menu bar; width; and height. Change those values to resize or reposition the window.
Then try playing with the front window
term. What if Safari has two windows open? Can you guess how to resize the back window? (It’s exactly what you think.) Then try changing the text of the dialog that appears if Safari has no windows open. And so on.
Sometimes an app doesn’t have an AppleScript dictionary at all. Or, it does, but it’s completely inadequate for your needs. In that case, you may be able to work around the problem using GUI scripting, which instructs AppleScript to simulate mouse clicks, button presses, menu commands, and the like—“playing” the user interface, as it were. It’s not foolproof, but it can solve otherwise intractable problems.
In GUI scripting, your script sends commands via a hidden app called System Events. System Events, in turn, tells a particular app (or other process) to click buttons, press keystrokes, and so on. (You’ll need to enable each app individually in System Preferences > Security & Privacy > Accessibility before they’ll respond to GUI scripting; this applies both to the target app and to apps that run scripts, such as Script Editor, Script Debugger, and UI Browser.)
For example, while creating scripts to go with Take Control of Your Paperless Office (about which I say more just ahead), I wanted a way to drive an OCR (optical character recognition) app called Readiris with an AppleScript. Readiris is not scriptable, but I was able to use GUI scripting to simulate button clicks and menu selections, which produced the necessary end result. Here’s a simplified version of the portion of the script that does that:
As you can see, as long as you can tell System Events precisely where to find a certain button or menu item, you can produce a click. (You can also send a keystroke with a command like keystroke "n"
or keystroke return
.) The problem, however, is that it’s often extremely difficult to ascertain the hierarchy of objects leading to the one you want—and worse, sometimes objects don’t respond to names at all.
Here, for example, is an actual line from an AppleScript I wrote:
Wow. So…how did I figure that out? Since nothing in the visible user interface tells me the names or numbers of all those groups of elements, how did I arrive at that hierarchy? Well, I used magic, which in this example was packaged into an app called UI Browser. (You can save 20 percent on UI Browser with a coupon at the end of this book.)
Among other capabilities, UI Browser lets you browse through any app’s hierarchy of objects (Figure 41)—something Script Debugger also does, albeit in a somewhat different form. But what makes UI Browser special is that it also lets you hover over any part of an app’s interface and see, in real time and from the perspective of System Events, what any object is called and exactly the path of containers that leads to it. It’s the easiest way I know to figure out how to script otherwise unscriptable apps.
That said, I should warn you that some apps defy even GUI scripting, usually because they’re little more than wrappers around custom Web browsers. For example, GUI scripting won’t get you anywhere with the team communication app Slack. What appear to be links and icons in the app are just part of a monolithic window as far as System Events is concerned. (In such cases, you may be still able to take a brute-force approach to automation, by simulating clicks at certain coordinates, but for such tasks I’d use something like Keyboard Maestro before trying to do something similar with AppleScript.)
To learn much more about GUI scripting, read the page Graphic User Interface (GUI) Scripting at Mac OS X Automation.
A folder action is an AppleScript that runs automatically when something happens to a specified folder—for example, you open or close it, or add files to it. In Take Control of Your Paperless Office, I described a situation in which your scanner saves PDF files to a certain folder—but what you want is for your OCR software to open the PDFs, recognize the text in them, save them as searchable PDFs, and then close them. No problem: attach one of my spiffy folder action scripts to the folder where your scans are saved, and all that can happen automatically.
Not just any old AppleScript can be a folder action; it must be written specially for that purpose. (For details, see the Folder Actions Reference page on Apple’s Developer site.)
In addition, before you can use folder action scripts, you must enable the system-wide Folder Actions capability (if you haven’t previously done so) and attach a particular script to the folder where your incoming scans are stored. Here’s how:
/Library/Scripts/Folder Action Scripts
folder or in ~/Library/Scripts/Folder Action Scripts
.Now, to use your folder action, drop a new file in the folder (or take whatever other action(s) the script supports, such as changing or removing files). The script should run automatically.
Here are a few further examples of things you could do with an AppleScript folder action:
I’ve barely scratched the surface of what you can do with AppleScript. If you want to learn more, allow me to recommend a few references: