Get Started with AppleScript

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.

Write a Simple AppleScript

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:

  1. Open Script Editor in /Applications/Utilities.
  2. In the window that appears, click New Document. A blank window opens.
  3. Type the word beep (Figure 34). Your script is now complete!
    **Figure 34:** Here’s your first complete AppleScript!
    Figure 34: Here’s your first complete AppleScript!
  4. Click the Run button.

Two things should happen:

  • First, you’ll hear your system alert sound. That was your program running—congratulations!
  • Second, you’ll notice that the word 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.

Learn What AppleScript Can Do

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.

**Figure 35:** A portion of the AppleScript dictionary for Calendar.
Figure 35: A portion of the AppleScript dictionary for Calendar.

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:

  • Find and remove duplicate messages in Mail, events in Calendar, or records in Contacts
  • Combine multiple PDFs into a single file
  • Apply proper title case to the names of all your tracks in iTunes
  • Rotate, resize, or change the format of images
  • Download all the MP3 files linked from a Web page
  • Rename all the files in a folder with a different extension
  • Count the number of email messages in a certain mailbox

I’ll give even more examples as the chapter goes on.

Understand AppleScript Basics

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.

Tell Blocks

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:

tell application "MyApp"
  tell front window
    do something
  end tell
end tell

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.

The Line Continuation Character

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:

display dialog "Wow, I have so much to say that I barely know ¬
  where to begin. Let’s start, I suppose, with my childhood…"

Variables

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.

Display Dialog

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:

  • Dialog with a message only (Figure 36):

    display dialog "Hi there"

    **Figure 36:** Dialogs can display hard-coded strings.
    Figure 36: Dialogs can display hard-coded strings.
  • Dialog with a message containing a variable (Figure 37):
    set firstName to "Joe"
    display dialog "Hi there, " & firstName
**Figure 37:** Dialogs can display the values of variables.
Figure 37: Dialogs can display the values of variables.
  • Dialog with a field, whose value goes into a variable (Figure 38):
    set firstName to text returned of ¬
      (display dialog "What is your name?" default answer "")
**Figure 38:** Dialogs can ask for text responses.
Figure 38: Dialogs can ask for text responses.
  • Dialog with custom buttons (Figure 39):
    display dialog "What rhymes with lunch?" ¬
      buttons {"Bunch", "Snack", "Table"} default button 1
**Figure 39:** Dialogs can have custom buttons.
Figure 39: Dialogs can have custom buttons.

If/Then Statements

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:

set myNum to 3
if myNum is less than 4 then
  display dialog "Yes, " & myNum & " is less than 4."
end if

(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.)

set firstName to text returned of (display dialog ¬
  "What is your name?" default answer "")
if firstName is "Joe" then
  display dialog firstName & " is awesome!"
else
  display dialog firstName & " is OK."
end if

Comments

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:

-- This is Joe’s excellent script. The next line sets a variable.
set myVar to "something"
-- Next we display that variable in a dialog.
display dialog myVar

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… *)

And That’s Just the Barest Beginning…

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.

Find and Run Example AppleScripts

Here are some simple scripts to try. To use one, copy and paste (or retype) it into Script Editor and click the Run button.

Tell me how many files and folders are on my desktop:
tell application "Finder"
  set theFolder to (path to desktop) as string
  set theCount to number of items in folder theFolder
  display dialog theCount
end tell
Speak the current date:
set theDate to current date
set theYear to year of theDate
set theMonth to month of theDate
set theDay to day of theDate
set niceDate to theMonth & " " & theDay & ", " & theYear as text
say niceDate
Apply some styles to a word in TextEdit:
set theStyle to {font:"Times", color:{26214, 0, 36237}, size:42}
tell front document of application "TextEdit"
  set properties of second word of first paragraph to theStyle
end tell
Resize the frontmost Safari window:
tell application "Safari"
  activate
  if front window exists then
    set bounds of front window to {0, 0, 1000, 600}
  else
    display dialog ("Safari has no open windows.")
  end if
end tell
Do a bit of simple math:
set firstNum to text returned of (display dialog ¬
  "Enter a number." default answer "")
set secondNum to text returned of (display dialog ¬
  "Enter a number." default answer "")
set operation to button returned of (display dialog ¬
  "What do you want to do with those two numbers?" ¬
  buttons {"Add", "Subtract", "Multiply"})
-- AppleScript dialogs can have a maximum of 3 buttons
if operation is "Add" then
  set theResult to firstNum + secondNum
else if operation is "Subtract" then
  set theResult to firstNum - secondNum
else
  set theResult to firstNum * secondNum
end if
display dialog "The result is: " & theResult

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).

**Figure 40:** The optional AppleScript menu displays both built-in and user-supplied scripts, letting you run them with one click (and without opening Script Editor).
Figure 40: The optional AppleScript menu displays both built-in and user-supplied scripts, letting you run them with one click (and without opening Script Editor).

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.

Edit an Existing AppleScript

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.

Use GUI Scripting

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:

tell application "System Events"
  tell process "Readiris"
    click button "OK" of sheet 1 of front window
    click menu "File" of menu bar 1
    click menu item "Export Document..." of menu ¬
      "File" of menu bar 1
  end tell
end tell

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:

click button "Convert to Text" of group 4 of group 12 of group 1 ¬
  of group 1 of group 3 of group 1 of group "Tools" of group 1 ¬
  of group 1 of group 1 of front window

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.

**Figure 41:** Browse an app’s hierarchy of UI objects in UI Browser.
Figure 41: Browse an app’s hierarchy of UI objects in UI Browser.

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.

Use AppleScript Folder Actions

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:

  1. Make sure whatever script you want to use is stored in the /Library/Scripts/Folder Action Scripts folder or in ~/Library/Scripts/Folder Action Scripts.
  2. Right-click (Control-click) on the folder you want to attach the script to, and from the contextual menu that appears, choose Folder Actions Setup (if you don’t see it at the top level of the contextual menu, look on the Services submenu). Folder Actions Setup opens.
  3. In the dialog that appears, select the script you want to use. (Although you can attach multiple AppleScripts to a single folder, I don’t recommend it. Pick a single script, and if need be, you can return to this dialog and change it later.)
  4. Make sure Enable Folder Actions is checked at the top of the Folder Actions Setup window. Your window should look something like Figure 42.
    **Figure 42:** You’re looking for approximately this end result (folder and script names may differ) after configuring Folder Actions.
    Figure 42: You’re looking for approximately this end result (folder and script names may differ) after configuring Folder Actions.
  5. Quit Folder Actions Setup.

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:

  • Get an alert when someone puts a new file in a shared folder. (Before I started running Take Control myself, I used to do this to learn when I had a new monthly royalty statement, which my publisher put in a shared Dropbox folder.)
  • Rename all the files dropped into the folder to follow a particular format or convention.
  • Upload the files to a Web server.
  • Move files to other folders on your Mac depending on file type, name, or other characteristics.

Learn More about AppleScript

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:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset