headbanger
headbanger

Reputation: 1112

How can I return an array into AppleScript from my scriptable program?

I'm trying to make my application scriptable, and one of the things that I'd like to be able to do is return an array from my application and into AppleScript so that it can be processed further there. I suppose I could do this by returning the count for the array, and then having AppleScript iterate from 1 to n to return each item from the array - but I don't think that this would be very efficient.

My code currently looks like this:

Relevant section of the sdef file

        <command name="List" code="lflecont" description="List file types found in data stream">
            <cocoa class="ListDataContentCommand"/>
            <result description="an array containing the types of all the data blocks in the File">
                <type type="any" list="yes"/>
            </result>
        </command>

ListDataContentCommand.h

@interface ListDataContentCommand : NSScriptCommand

@end

ListDataContentCommand.m

@implementation ListDataContentCommand

-(id)performDefaultImplementation {
    return @[@"Jam",@"Fish",@"Eggs"];
}

@end

To test this, I've created the following simple AppleScript…

tell application "Data Dump"
    open "/Volumes/Test Data/test.dat"
    set theList to List
end tell

This returns an error - error "Data Dump got an error: Can’t continue List." number -1708

How can I get my array to be output?

For that matter, how can NSDictionary be returned? Or is that impossible? And can NSString be returned straight to text - or does it need to be converted to a Cstring first?

Newbie questions, I'm afraid, but good information on AppleScript seems to be quite hard to come by!

Upvotes: 0

Views: 379

Answers (1)

Ted Wrigley
Ted Wrigley

Reputation: 3194

Generally speaking, if you want to return an list of items through AppleScript, you set up the sdef's command XML as follows, expanding the result element to a block and including a type element with the list attribute set to 'yes':

<command name="List" code="lflecont" description="List file types found in data stream">
    <cocoa class="ListDataContentCommand"/>
    <result description="an array containing the types of all the data blocks in the File">
        <type type="any" list="yes"/>
    </result>
</command>

Then at the end of your performDefaultImplementation method all you need to do is return a standard cocoa NSArray. Cocoa scripting automatically translates the array into an AppleScript list, converting all subelements into appropriate forms.

-(id)performDefaultImplementation {
    NSArray * resultArray

    // do whatever that adds values to resultArray
    return resultArray;
}

The one concern I have is that you seem to be doing something with notifications, and if the output depends on an asynchronous operation (like a notification reply) you may need to start thinking about suspending and resuming the apple event. Remember, AppleScript is not threaded, so if the app is processing one event (waiting for an asynchronous operation) and receives a second event, the outcome is indeterminate (and likely unpleasant).

Upvotes: 1

Related Questions