Adding Custom Applescript Commands to an Applescript Studio Application
While it’s always possible to script an Applescript Studio Application using GUI scripting, it’s pretty clunky to constantly be referring to windows and buttons. The good news is that it’s not too difficult to add custom commands to your application. However, you will need to know some Objective-C to do this.
Creating the scriptSuite and scriptTerminology Files
The first thing you should do is download suiteModeler. This is a very handy tool for creating the scriptSuite and scriptTerminology files that you need to create your custom grammar (read more about them on Apple’s website). The best thing about this tool is that it’s FREE! You also might want to check out the sample programs on this page.
After you launch suiteModeler, you’ll see the Suite screen. The Suite name is generally the same name as your application, we’ll use MyApp in this example. The Apple Event Code is a universally unique 4-letter code for your application. For this example, we’ll use MyAp. You’ll want to register your code with Apple to make sure that you don’t stomp on another application’s Applescript events. That’s all you need to fill in for this tab.
The next tab to look at is the Commands tab. Click the + button to create a new command. Under name supply a name with no spaces or special characters. For ext. name, specify the actual syntax for this command that you want to use in the Applescript code. command class will contain the name of an Objective-C class that you will implement in your project to handle the operation of the new command. The code field is another 4-letter code that should be unique with in your application (it actually just needs to be unique within the class code, but for our simple example class code will just be set to the same code a 4-letter code that we used on the Suite tab). The type column contains the type of argument that the command will take. If you don’t have an argument, you don’t have to specify anything. The result code is the return code type for the command. Again, if you aren’t returning anything, leave it blank. The verb column specifies whether the command begins with a verb or an object. For the method described in this article, you want to set this to YES.
For the purposes of this example, we’ll use the following values for the command fields:
| name | DeliverMessage |
|---|---|
| ext. name | deliver message |
| command class | DeliverMessageCommand |
| code | Dlvr |
| class code | MyAp |
| type | NSString |
| result code | |
| verb | YES |
If you have other arguments to your command, you can add them in the Arguments pane at the bottom of the Commands tab. The fields there are very similar to the fields in the command section.
Now that you have your command defined, go to the File menu and save the plist files to your project directory. You can then add those files into your Applescript Studio project.
Command Implementation
You should now have your scriptSuite and scriptTerminology files in your project. This means that you should be able to talk to your application using Applescript, of course, you haven’t implemented the command yet not much is going to happen. To begin the implementation of the command you need to add a New File to your project under the File menu. This “file” will be an Objective-C class. Use the same name for this class that you specified in the command class field of the command setup (DeliverMessageCommand in our example).
In the .h file, you only need to make one small change. Change the NSObject super class name to NSScriptCommand. The .m file is where the real action is. All you need to do here is implement the performDefaultImplementation method. To get the arguments of your Applescript command, you will use the following:
// Accesses the argument of the commond [self directParameter]; // Accesses named arguments of the command [[self evaluatedArguments] objectForKey:@"ArgumentName“];
Since we are adding this implementation to an Applescript Studio application, we need a way for our Objective-C class to talk to our Applescript code. The trick I used is simply to use more Applescript. I instantiate an NSAppleScript object and execute some code. The code you execute will probably be some of that ugly GUI scripting that you were trying to avoid in the first place, but at least now it will be buried away in your class files. In the example below, the title of a button is set to the message we want to display and the button is told to perform its action. Of course, you’ll need to connect that button to an on clicked event in your application to do the real work.
#import "DeliverMessageCommand.h"
@implementation DeliverMessageCommand
-(id)performDefaultImplementation
{
//
// tell application "MyApp"
// set eventbutton to button "message" of window "MyApp"
// set title of eventbutton to "directParameter”
// tell eventbutton to perform action
// end tell
//
NSString *script = [NSString stringWithFormat:@”tell application ”MyApp”
nset eventbutton to button ”message” of window ”MyApp”
nset title of eventbutton to ”%@”
ntell eventbutton to perform action
nend tell”, [self directParameter]];
[[[NSAppleScript alloc] initWithSource:script] executeAndReturnError:nil];
return nil;
}
@end
Now all you need to do is build your project and you should be able to call this command with Applescript as follows.
tell application "MyApp" deliver message "ramblings of distinction" end tell
