Online Book Reader

Home Category

AppleScript_ The Definitive Guide - Matt Neuburg [20]

By Root 1524 0

Cocoa


As an example of incorporating AppleScript into a standard application, I'll recreate the previous example as a Cocoa application written in Objective-C. The task is more involved than in AppleScript Studio, because we must twice "cross the bridge" between Objective-C and AppleScript: from Objective-C we must summon AppleScript, and we must translate the response from AppleScript to Objective-C (whereas with AppleScript Studio there's no need for any of that, because the program is already written in AppleScript).

Cocoa has an NSAppleScript class that accepts and executes AppleScript code. There are two approaches: you can start with a string and compile and execute it, or you can start with a compiled script and execute that. Here's code demonstrating the first approach:

- (void) awakeFromNib {

[self willChangeValueForKey:@"diskList"];

diskList = [[NSMutableArray alloc] init];

NSAppleScript* scpt = [[[NSAppleScript alloc] initWithSource

:

@"tell application \"Finder\"\r"

"get name of disk 1\r"

"end tell"]

autorelease];

NSAppleEventDescriptor* result = [scpt executeAndReturnError

: nil];

if ([result descriptorType] == 'utxt')

[diskList addObject: [result stringValue]];

else if ([result descriptorType] == 'list') {

int i, u = [result numberOfItems];

for (i=1; i<=u; i++)

[diskList addObject: [[result descriptorAtIndex: i] stringValue]];

}

[self didChangeValueForKey:@"diskList"];

}

Even if you don't know any Objective-C, you can get a sense of what's going on here. Within the awakeFromNib method, the first two lines and the last line have essentially to do with the interface, and needn't concern us except to say that there is an instance variable diskList (an NSMutableArray) and whatever we put into it is going to show up in the interface as a line of the list displayed in our window. There are three lines where we form a literal string constituting our AppleScript code (the same code used in Figure 2-1); this string is slightly complicated because we must "escape" its quote characters, just as in the FileMaker code earlier in this chapter ("Internally Scriptable Application"), and we must explicitly insert "escaped" return characters. The next line (starting with the word NSAppleEventDescriptor) is where we ask for this AppleScript code to be compiled and executed.

After that, we have to do a surprising amount of work (and in fact we should be doing even more—I've deliberately omitted error checking, to condense the presentation). The problem is that when the reply comes back, we have to parse it differently depending on its type. This is all stuff that's taken care of for us when we get a result in a script editor application, but here we have to do it ourselves. If there's only one disk, the result will be a string; we insert that into diskList and that's that. If there's more than one disk, the result will be a list of strings, so we have to cycle through that list and insert each string into diskList. (The main surprise here for an experienced Cocoa programmer is that list indexes in an Apple event, unlike Objective-C collections, are 1-based!)

The other approach, probably faster, would be to compile the AppleScript code beforehand and incorporate the compiled script file into the project. When the application is built, the compiled script file is copied into its bundle as a resource. Instead of constructing the AppleScript code as a string, we retrieve the compiled script file from the bundle. So, for example, if the compiled script file is called askFinder.scpt, the relevant line of code (where we create our NSAppleScript object) would be changed to this:

NSAppleScript* scpt = [[[NSAppleScript alloc] initWithContentsOfURL

:

[NSURL fileURLWithPath:

[[NSBundle mainBundle] pathForResource: @"askFinder" ofType: @"scpt"]]

error: nil] autorelease];

The result when the application runs is a window that appears identical—and I do mean identical—to Figure 2-8; so I won't bother to repeat the screenshot.

Unix


Mac OS X, under the hood, is Unix . It is possible to use AppleScript

Return Main Page Previous Page Next Page

®Online Book Reader