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.
Things look mostly right, but the code for the <command/>
should be a two-part code (eight characters) and not four.
I just posted a detailed solution on how to add a command with argument here: https://stackoverflow.com/a/10773994/388412
In short: I think you should subclass NSScriptCommand and override -(void)performDefaultImplementation rather than exposing a method in your controller. At least that's what I distilled from the docs:
"This command is a subclass of NSScriptCommand, containing one method, performDefaultImplementation. That method overrides the version in NSScriptCommand"
… and it works fine for me, see my linked answer for details.
(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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With