MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


AppleScript Primer for Mac OS X

by Bruce W. Perry, author of AppleScript in a Nutshell
02/01/2002

AppleScript is a built-in Macintosh automation tool that gives users the ability to control the operating system and several of their favorite applications. While this powerful scripting system has always had a loyal following of Macintosh aficionados and publishing professionals, the release of Mac OS X 10.1.2 may mean AppleScript is ready to strut its stuff in front of a wider audience. Here are some of the exciting AppleScript developments on Mac OS X:

In this article, I'll begin by showing you where to find the applications in which you develop your AppleScripts. Then, to get you going, I'll give an example of a simple AppleScript. Since you are interested in not just the simple but the sublime, I'll also give you descriptions and code samples relating to AppleScript Studio, Web services, and Unix-shell integration.

Related Reading

AppleScript in a NutshellAppleScript in a Nutshell
By Bruce W. Perry
Table of Contents
Index
Sample Chapter
Full Description

For those who are eager to dive into scripting their favorite Mac OS X and third-party applications, such as Adobe Illustrator 10 or FileMaker Pro, refer to the sidebar "Scriptable Mac Applications" for a list of applications that can be used with AppleScript.

For Starters

You can find AppleScript by opening a new Finder window, clicking on the "Applications" icon, then opening the AppleScript folder. There you will find the Script Editor application. (You can also type in Option:Command:A to get to the Applications folder.) Figure 1 shows a Script Editor window and a Finder window in column view, with the AppleScript folder selected. Script Editor is similar to a text editor where you can type in, check the syntax of, and compile AppleScripts.

Applescripting Window

Here's a simple scripting example. I use a printer that is connected to a Windows machine in another part of my office. While I have not been able to add documents directly to this machine's print queue, I can keep the other machine's disk mounted on my laptop's desktop and move the files that I want to print into a "print" folder on that distant machine (from where they are printed). Here is the AppleScript that does it:

Scriptable Mac Applications

Here is a list of some of the Mac OS X applications can be controlled by AppleScripts:

Apple System Profiler
ColorSync
Finder
Image Capture
iTunes (See the "Scripting iTunes 2" sidebar)
Mail
Print Center
QuickTime Player
Sherlock
Terminal
TextEdit
Interface Builder
Project Builder

Here’s a short list of scriptable third-party applications:

Adobe Illustrator
Adobe Photoshop
BBEdit
Eudora Email
FileMaker Pro
Internet Explorer
Microsoft Word
Netscape Navigator
QuarkXPress
Stone Studio

tell application "Finder"

   activate
   move selection to folder "print" of disk "M"

end tell

This script targets the Finder application with its script messages, which are technically referred to on the Macintosh as Apple events. The "tell" block contains the statements that its specified application understands; you probably guessed that to target other applications with AppleScript you use syntax such as " tell application "iTunes" " or " tell application "Adobe Photoshop®5.5"".

The "activate" command makes the targeted application the active layer on the desktop (so the program’s menu is displayed on the top of your screen). The file that is selected in the Finder is then moved to a folder called "print" on a disk named "M" (on another machine in this case). To keep things simple we have not checked if the selected item is a file or not (we may not want to move any folders), but this example should suggest how easy it is to get started with concise and useful scripts. A few applications (such as BBEdit 6.5) will generate the AppleScript for you via Script Editor's "Record" feature. Of course, you can do much more with AppleScript.

AppleScript Studio

The marquee feature of Mac OS X 10.1.2 for script mavens is AppleScript Studio. This tool allows you to develop great-looking Aqua interfaces for an AppleScript application. For example, Figure 2 shows the window for an AppleScript Studio application that asks the user for a stock symbol, then goes and grabs the stock value using Web services and the chosen currency for the display format.

AppleScript Studio has been incorporated into an existing integrated development environment (IDE) consisting of Project Builder and Interface Builder, the same tools that are used to create Cocoa applications in the Java or Objective-C languages. AppleScript Studio is included with the December 2001 Mac OS X Developer Tools (see http://developer.apple.com/tools/macosxtools.html ), which are a free download for Apple Developer Connection members. An ADC online membership is free, so it's a great deal to be able to develop your own Mac OS X software with this feature-rich and free-of-charge IDE.

Applescript Studio Window

AppleScript Studio is quite a step up from Script Editor, in both functionality and learning curve. In an AppleScript Studio application, you can optionally add new Java and/or Objective-C classes to your project in Project Builder, then call the methods of these objects directly from AppleScript. Creating sophisticated interfaces in Interface Builder is as easy as dragging and dropping Cocoa interface objects (such as text fields, buttons, and progress indicators) from a palette onto an AppleScript Studio application window. Figure 3 shows a Studio application window and palettes in Interface Builder.

Studio app and palettes

AppleScript Studio looks like a promising development environment for automation suites that require user interaction.

Hello Unix Shell

AppleScripters can use the Unix shell in two different ways with Mac OS X 10.1.2. The "do shell script" command executes a Unix shell statement without having to target a specific application. For example, type the following script into a Script Editor window, then compile and run it. It will issue three Unix shell commands, each separated by a semi-colon.

   do shell script "cd $HOME; pwd; ls -l"

The script then receives the return value as a string (a bunch of characters, like a written sentence, surrounded by quote marks), which it can then process as needed. Here is a portion of the return value of the latter script:

      "/Users/brucep
total 0
drwxr-xr-x   7 brucep  staff   264 Nov 24 20:27 AllProps
drwxr-xr-x   5 brucep  staff   126 Jan  4 19:57 Applications
drwx------  17 brucep  staff   534 Jan 18 10:24 Desktop
drwx------  14 brucep  staff   432 Jan 18 10:17 Documents
..."

Scripting Terminal

You can also script the Terminal application, which is the command-line utility installed with Mac OS X. The following script will open up a new Terminal window and launch the Apache Tomcat Java servlet engine and MySQL database server. Very useful!

ignoring application responses
   tell application "Terminal"
      activate
      do script with command ¬ 
      "/Users/brucep/bin/start_tomcat; /usr/local/bin/safe_mysqld &;"
   end tell
end ignoring

The "¬" character, a line-continuation character, is produced on the Mac by typing option:return. The "ignoring application responses/end ignoring" block will prevent the AppleScript from stalling while it waits for a response from Terminal. One source of more information on the "ignoring" AppleScript statement is on page 137 of my book, AppleScript in a Nutshell.


Sidebar: Scripting ITunes 2

Here is a script that opens up iTunes 2 and lets the user choose a song by its title, then plays the song.

tell application "iTunes"
	
activate
try
   set mainWindow to item 1 of browser windows
   set _playlist to the view of mainWindow
   set theSongs to the name of every track of _playlist
   set songTitle to ¬
      choose from list theSongs with prompt ¬
         "Choose a song to play"
   tell _playlist
      set song to item 1 of ¬
         (every track whose name contains the songTitle)
   end tell
   say "Now playing the song " & (name of song) & ¬
          " by " & (artist of song)
   play song
on error	
   display dialog ¬ 
"Either a playlist is not selected or you canceled the dialog.
Please try again."
end try
end tell

This script displays all the song titles for the tracks that are contained by iTune's main window. The user can then select a song title from a list that appears in a dialog window (the script part "choose from list theSongs" produces this song-filled dialog). The “say” AppleScript command will cause the computer to speak whatever phrase you feed to the command. The voice for this command is configured in Mac OS X's Speech preferences, which is found in the System Preferences window. You can even use “embedded speech commands” to modify how the “say” AppleScript command reads the text. See pg. 393 of “AppleScript In A Nutshell” for more information on embedded speech commands.


Web Services

Web services are XML applications that exchange focused bits of information between distant computers. These services include two protocols: XML-Remote Procedure Call (XML-RPC) and Simple Object Access Protocol (SOAP). Without getting too deeply into the technical stuff, both of these protocols use Hypertext Transfer Protocol (HTTP), the same data-transfer method as the Internet, to send and receive information remotely. Both the requests and the responses in XML-RPC and SOAP are formatted as XML. AppleScript on Mac OS X 10.1.2 makes it easy to use both XML-RPC and SOAP.

Call xmlrpc

Starting with Mac OS X 10.1, scripters can use the "call xmlrpc" command. You begin by targeting an XML-RPC server in a "tell" AppleScript block. The following script queries an XML-RPC server at "http://time.xmlrpc.com/RPC2" for the date and time. It's just a simple example; there are numerous other types of data that are accessible from SOAP and XML-RPC servers. The "call xmlrpc" command requires a method name ( as in "currentTime.getCurrentTime"). You have to include any required parameters with the method (see the "call soap" example). The script takes the return value and makes an AppleScript date out of it. The code also adds three hours to the return value to bring it in line with the Eastern U.S. time zone.

tell application "http://time.xmlrpc.com/RPC2"
	
   set returnValue to call xmlrpc ¬
      {method name:"currentTime.getCurrentTime"}
   set theDate to (returnValue as date) + (3 * hours)
	
end tell

The Web sites that provide Web services will usually explain what method names and parameters to use (see "http://www.xmlrpc.com/currentTime" for details on this script sample). Whether you like it or not, the Mac OS X system software takes care of the XML for you. The AppleScripter doesn't have to deal with parsing or translating the XML return value.

Call soap

The AppleScript command for using SOAP servers is predictably, "call soap." SOAP is a more complex protocol than XML-RPC, partly because SOAP allows you to exchange more complex datatypes. The AppleScript syntax is a little more lengthy for SOAP calls. Along with the "call soap" syntax, you have to provide values for the method name, “method namespace URI,” any method parameters, and the “SOAPAction.” Sites such as XMethods (where I found this SOAP server information) usually explain what default values to use for these various parameters. You couldn't possibly guess them!

This script gets a stock price (live, if the stock market is open) in a certain currency by providing the stock symbol and country name as parameters. In this case, we are using Sun Microsystems with the stock value in U.S. dollars. The odd looking "on getStockPrice(sym, _country)" part is an AppleScript handler that takes a stock symbol and a country name as parameters, then uses the “call soap” command to return the stock price. AppleScript handlers or subroutines are described in Chapter 8 ("Subroutines") of the AppleScript in a Nutshell book.

set sym to "SUNW"
set _country to "United States"

getStockPrice(sym, _country)

on getStockPrice(Symbol, theCountry)
   try
      with timeout of 30 seconds	
         tell application "http://soaptest.activestate.com:8080/PerlEx/soap.plex"
				
            return (call soap ¬
            {method name:"StockQuoteInCountry", ¬
            method namespace uri:"http://activestate.com/",¬
            parameters:{Symbol:Symbol as string, country:theCountry as string},¬
            SOAPAction:"urn:activestate"} )
				
         end tell
      end timeout
		
   on error errmesg
      display dialog errmesg
   end try
end getStockPrice

More AppleScript Information

AppleScript Web site

O'Reilly's AppleScript in a Nutshell

The AppleScript Studio home page

Apple Computer's detailed guide to AppleScript Studio

Apple Computer's AppleScript Guidebook modules

Apple Computer's detailed guide to AppleScript and XML-RPC, SOAP

The XML-RPC Specification

The "getStockPrice" handler includes an AppleScript "try" block, which can catch and optionally deal with any errors that occur in the script statements appearing within "try … end try." In terms of SOAP or XML-RPC calls, the response can be delayed by a network slowdown, and this can cause the script to "time out" in AppleScript parlance. Without using the "try" error-trapping statement, the script may crash gracelessly. The script also uses the "with timeout" statement to limit to 30 seconds the amount of time the script waits for a response to its SOAP request.

Web services are a very important development in the software world. It is very exciting that AppleScript has such clean integration with them.

Go for It

We have just only scratched the surface on the expansive possibilities for users and developers of AppleScript on Mac OS X. A likely subject for several future articles are the number of major applications that offer scripting support using AppleScript.


O'Reilly & Associates published (June 2001) AppleScript in a Nutshell.

Copyright © 2009 O'Reilly Media, Inc.