Write Your Own Automator Actionsby 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.
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.
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:
In Interface Builder, draw the interface.
In Interface Builder, bind the interface widgets to the object controller.
In Xcode, write the Action's code.
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.
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
(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
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.
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.
NSTextFieldto the n key (binding the
Pages: 1, 2