0

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!

3
  • 1
    Usually the standard types NSString, NSNumber and NSDate are bridged implicitly to the AppleScript types. By default AppleScript works synchronous, the ListDataContentCommand script command returns nil (missing value on the AppleScript side). If you need asynchronous processing you have to call suspend and resume on the current script command. And what is the real return type? If you use any you have to return NSAppleEventDescriptor. To return a dictionary you have to create a record-type in the sdef file. Commented Mar 23, 2021 at 20:48
  • So to return an NSArray, I have to set it to return a list (in the sdef)? Have I understood that correctly? <result type="list" - and then that NSArray needs to be returned from performDefaultImplementation (obviously)? Commented Mar 23, 2021 at 21:22
  • No, define the real return type and add list="yes". And the id return type covers also NSArray Commented Mar 23, 2021 at 21:31

1 Answer 1

1

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).

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for this. I've updated the question - because, to simplify matters and test what I've got, I did what you said - and I get a Can't continue…
@headbanger: Just because it's a good idea, you probably shouldn't call your command 'List'; AppleScript is case sensitive, but it's too close to the AS defined 'list' object. Also, you shouldn't capitalize without reason. Try renaming the command 'list types' and see if that fixes anything. Also, quit and reopen Script Editor when you make SDEF changes; the Script Editor caches scripting information, so you need to force it to update.
@headbanger: I'll have to do some experimenting tonight. All the commands in my current scriptable app project return objects rather than values, so I'll need to mock something up.
Thanks for your suggestions - I changed it to list_objects, but the error is just the same. That said, if I return @[] then it's happy - and it shows an empty list. Which might be a clue
@headbanger: you might try (as a test) setting the type attributes to type="text" and see if that changes things. If that's the problem, you may need to explicitly create and return an apple event descriptor for the reply apple event (when you use type 'any', in any case).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.