oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Write Your Own Automator Actions

by Matt Neuburg

Mac OS X 10.4 (Tiger) introduces Automator, which lets users string together preinstalled script steps (Actions) into a sequence (Workflow) that can be run and saved. The sequence is a rudimentary data flow, or pipe: typically, each step outputs some data, which becomes the input to the next step. The advantage for the user is that there's no need to know a scripting language in order to write and run a custom sequence.

Figure 1. A simple Automator workflow; it writes the pathnames of all files in a given folder into a new TextEdit document Figure 1. A simple Automator workflow; it writes the pathnames of all files in a given folder into a new TextEdit document

Besides the more than 200 Actions installed by default in /System/Library/Automator, we may expect to see many third-party Actions in the near future, which the user will install in /Library/Automator or ~/Library/Automator. You, the developer, can participate in this movement by writing and distributing your own Actions.

This prospect is particularly attractive to AppleScript programmers. (It is also possible to write an Action in Objective-C, but AppleScript is usually more appropriate because typically an Action communicates with some scriptable application.)

An Action is a convenient way to distribute a script. The script is bundled inside the Action and cannot be read. The script is in the form of a handler, accepting a certain type of data and outputting a certain type of data, and Automator enforces your declarations of these data types so the end user can't misuse it. Thus, thanks to Automator's data flow architecture, the end user can easily take advantage of your script's functionality to operate on and generate data as part of a custom sequence without ever coming in direct contact with the code, and with no need to grapple with the mysteries of a scripting language.

Four-Step Program

An Automator Action is extremely easy to write. Documentation on how to do so is copious and helpful; take a look in the ADC Reference Library on your hard disk, under ...documentation/AppleApplications/Conceptual/AutomatorConcepts/Automator.html. Still, all that documentation may seem overwhelming at first, so this article presents a simple hands-on example to get you started down the road to writing your own Actions.

We'll write our Action in AppleScript, but it will be a very simple and silly example and won't do any interapplication communication; it merely takes the text provided as input and returns every nth word, where n is to be provided by the user in Automator's interface. Hey, it's only an example!

There are four steps to writing an Action:

  1. In Interface Builder, draw the interface.

  2. In Interface Builder, bind the interface widgets to the object controller.

  3. In Xcode, write the Action's code.

  4. In Property List Editor, edit the Action's Info.plist file.

You can then run and test the Action within Automator.

Create the Project, Draw the Interface

Start up Xcode 2.0, choose File -> New Project, and select AppleScript Automator Action. The name you give the project will be used as the name of the Action, so make it meaningful; let's call it Every Nth Word.

When the project appears, open main.nib. You're now in Interface Builder. In the main window, you'll see a View instance; open it. This is where you'll design the interface that the user will see for this Action within Automator.

Figure 2. The default Action nib, ready for you to draw the interface Figure 2. The default Action nib, ready for you to draw the interface

Select the existing label in the view ("UI elements go here") and delete it. Now create the new interface within the view. In our case, we just need an NSTextField where the user can enter a number, and a label explaining what to do with it. As a crude way of enforcing the requirement that the user enter a number in the NSTextField, I've made the NSTextField noneditable, and I've added an NSStepper, on which the user must click to change the number in the NSTextField.

Figure 3. Our Action's interface Figure 3. Our Action's interface

(The View is displayed at a minimum width, which you should not change. You may, however, change its height to accommodate more interface or to eliminate empty white space. In real life, you might also want to add "springs and struts" to the interface widgets in case the user widens the Automator window.)

And in the Darkness Bind Them

When our Action runs, we will need to know the user's settings in its interface. The mechanism by which we will acquire this information involves Cocoa bindings. That is what the NSObjectController object called Parameters is doing in the main.nib main window (see Figure 2). For every value in the interface that we want to hear about, it is up to us to give this NSObjectController a key, and to bind the interface widget to that key.

In this case, there is just one value we need to know about--the number selected by the user, using the NSStepper, that appears in the NSTextField. Let's call the key for that number n. Select the Parameters instance in the main.nib window and open the inspector window to the Attributes pane. Click on the Add button, double-click on the NewKey entry, and type n (and hit the Tab key). We have created the n key.

 Figure 4: Creating the n key for the Parameters NSObjectController Figure 4. Creating the n key for the Parameters NSObjectController

Now we must bind our interface to the n key. In this case, we must bind both the NSTextField and the NSStepper to the n key, so that their values stay synchronized. (When the user changes the NSStepper value, the NSTextField should change to reflect the new value.) Select the NSTextField in the View, switch the inspector window to the Bindings pane, and bind its Value to n. Do the same with the NSStepper. Save the nib and quit Interface Builder; we're done with it.

Figure 5. Binding the NSTextField to the n key (binding the NSStepper is similar) Figure 5. Binding the NSTextField to the n key (binding the NSStepper is similar)

Pages: 1, 2

Next Pagearrow