views:

569

answers:

2

I'm trying to add some scripting functionality to a Cocoa app that I've written. I've created an sdef (Scripting Definition File) for my project. So far I have been successful in accessing object children (elements) with AppleScript but I cannot for the life of me figure out how to call methods (commands).

Here is my sdef file.

<suite name="mySuite" code="mSUI" description="My Application Suite">
    <class name="application" code="capp" description="Top level scripting object.">
        <cocoa class="NSApplication"/>
        <!-- I can access these elements fine -->
        <element description="Test children." type="child" access="r">
            <cocoa key="myChildren"/>
        </element>
        <!-- Cannot seem to call this method :( -->
        <responds-to command="testmethod">
            <cocoa method="exposedMethod:"/>
        </responds-to>
    </class>
    <class name="child" code="cHIL" description="A Child." plural="children">
        <cocoa class="Child"/>
        <property name="name" code="pnam" description="The child name." type="text" access="r">
         <cocoa key="name"/>
        </property>
    </class>
    <command name="testmethod" code="tEST" description="Execute the test method" />
</suite>

Here are my controller class implementations (this is the delegate of my application)

MyController.h

#import <Cocoa/Cocoa.h>

@interface MyController : NSObject {
    NSMutableArray* myChildren;
}
// Some Methods

@end

MyController+Scripting.m

#import "MyController+Scripting.h"

@implementation MyController (Scripting)

// This works when I'm accessing the myChildren 
- (BOOL)application:(NSApplication*)sender delegateHandlesKey:(NSString*)key { 
    NSLog(@"Key = %@", key);
  return ([key isEqualToString:@"myChildren"]);
}
// This does NOT work...
- (void)exposedMethod:(NSScriptCommand*)command {
    NSLog(@"Invoked Test Script Method %@", [command description]);
}

@end

Lastly, the AppleScript I am trying is:

tell application "MyApplication"
    testmethod
end tell

which responds with "AppleScript Error - The variable testmethod is not defined."

Any ideas what I'm doing wrong here? I feel like I'm missing something simple but my Googling doesn't seem to be turning up anything helpful.

+1  A: 

(I've actually never added scriptability to a Cocoa app, so take my stab in the dark with a grain of salt.)

The first thing I would guess is that exposedMethod: takes a parameter, but I don't see where one might be specified in your sdef or AppleScript. In fact, it looks like AppleScript is treating testmethod as a variable, not a command. (Maybe it should be something like "testmethod with ..." instead?) You may need to define a <parameter> or <direct-parameter> element for the command in the sdef.

Also, wouldn't you need an object to call the method on? Since your controller is the application delegate, I'm not sure of the intricacies there, but might AppleScript try to invoke testMethod: on NSApplication instead of your delegate?

I'm guessing you've looked at Apple's sample code and other resources, but if not, here are a few links that may help:

Good luck!

Quinn Taylor
The parameter to that method is an instance of NSScriptCommand, which encapsulates any Apple Event parameters that may have been passed along. All script-command methods take one of those as an argument.
Ben Stiglitz
+1  A: 

Things look mostly right, but the code for the <command/> should be a two-part code (eight characters) and not four.

Ben Stiglitz