Apologies for posting this late. I was finishing up the test app and filing relevant bugs.
So, how do you run an AppleScript script?
One way is NSAppleScript
. The problem with that is that, in our experience on the Adium project, it leaks memory. Profusely. (Maybe this has changed; Adium has for a long time used a separate process for running AppleScript scripts.)
Another way is to use the Open Scripting Architecture API directly. But that API is pre-Carbon, making it painful to deal with. One specific problem is that the object types aren’t reference-counted.
The third way is OSAScript
, one of the classes in OSA Kit.
Wait. OSA Kit?
Yes. OSA Kit is an Objective-C wrapper around the Open Scripting Architecture. Like QTKit (a similar wrapper around QuickTime), it’s a framework in Mac OS X that Apple added in version 10.4. It’s public, but undocumented: As of right now, searching developer.apple.com for that name yields exactly five hits, none of which are documentation of OSA Kit.
One of those hits is the list of system frameworks, which says that OSA Kit:
Contains Objective-C interfaces for managing and executing OSA-compliant scripts from your Cocoa applications.
OSA-compliant… like AppleScript!
The interface for OSAScript
is the same as that of NSAppleScript
, except larger: OSAScript
is a superset of NSAppleScript
. This is mostly because the OSA supports languages other than AppleScript, such as JavaScript (with this component). Running a script, for example, is no different:
NSDictionary *errorDict = nil;
script = [[[(OSAScript | NSAppleScript) alloc] initWithContentsOfURL:scriptURL error:&errorDict] autorelease];
result = [script executeAndReturnError:&errorDict];
But, unlike NSAppleScript
, the OSA Kit does not stop there.
OSA Kit is to Script Editor as Image Kit and PDF Kit are to Preview. Apple removed those applications’ capabilities to a new framework, and rewrote the applications to use the new frameworks. In the process, they added features and made the existing features prettier.
In the case of OSA Kit, the new framework includes classes you can use to build your own Script Editor (or CLImax)—specifically, OSAScriptView
and OSAScriptController
. You may find these classes useful if you plan to embed some of Script Editor’s functionality into your application.
Of course, you don’t need to use OSA Kit from an application. Here’s a command-line tool I wrote:
OSA Kit does have some downsides:
- As I mentioned, it isn’t documented. All we have to go on are the headers.
- There’s not even sample code, other than the example I wrote and included in this very post.
- Calling a handler by name with arguments doesn’t work (hence the “theoretically” above). I believe that this is a bug in
OSAScript
; I have filed it, with a summary of -[OSAScript executeHandlerWithName:arguments:error:]
always returns an error, never executes the handler.
There is also one potential downside: I don’t know for certain that OSAScript
doesn’t leak memory the same way NSAppleScript
does (or did). It’s worth trying, though, and it’s more capable anyway.
I consider the OSA Kit to be the future of running AppleScript scripts from Objective-C.
UPDATE 2008-11-09 13:18 PST: Replaced OSAKit osascript 1.0 with 1.0.1, which has a couple more sample scripts.
UPDATE 2008-11-09 17:40 PST: Changed link to CLImax. I had linked to Drew Thaler’s blog post announcing its re-release; now I’m linking to the actual product page, as saved by the Internet Archive’s Wayback Machine.
UPDATE 2008-11-11 20:43 PST: Replaced OSAKit osascript 1.0.1 with 1.0.2, which has better (more GCC-like) error-reporting.