I am trying to write an AppleScript that calls my Swift application to get a value. The method takes a string and needs to return another string.
Here is my .SDF file:
<suite name="My Suite" code="MySU" description="My AppleScript suite.">
<class name="application" code="capp" description="An application's top level scripting object.">
<cocoa class="NSApplication"/>
<element type="my types" access="r">
<cocoa key="types"/>
</element>
</class>
<command name="my command" code="MyCOMMND" description="My Command">
<parameter name="with" code="MyPR" description="my Parameter" type="text">
<cocoa key="myParameter"/>
</parameter>
<result type="text" description="the return value"/>
<cocoa method="myCommand:"/>
</command>
</suite>
The corresponding Swift code is fairly simple:
func myCommand(_ command: NSScriptCommand) -> String
{
if let myParameter = command.evaluatedArguments?["myParameter"] as? String
{
return "Hello World!"
}
else
{
return "Nothing happening here. Move on."
}
}
and finally my AppleScript is here:
tell application "MyApp"
set r to my command with "Hello"
end tell
When I execute the AppleScript it recognises my command, but it does not call the Swift code that I've tried to associate with it. Neither Xcode or AppleScript report a problem. Have I misses something out or put my code in the wrong place?
For this sort of scripting I would recommend a command-first (aka verb-first) approach rather than the object-first approach you are attempting. Your sdef would look like this (replacing "MyProject" with the name of your project, i.e. your application's Swift module name):
<dictionary xmlns:xi="http://www.w3.org/2003/XInclude">
<suite name="My Suite" code="MySU" description="My AppleScript suite.">
<command name="my command" code="MySUCMND" description="My Command">
<cocoa class="MyProject.MyCommand"/>
<parameter name="with" code="MyPR" description="my Parameter" type="text">
<cocoa key="myParameter"/>
</parameter>
<result type="text" description="the return value"/>
</command>
</suite>
</dictionary>
The MyCommand
class should look like this:
class MyCommand : NSScriptCommand {
override func performDefaultImplementation() -> Any? {
if let _ = self.evaluatedArguments?["myParameter"] as? String
{
return "Hello World!"
}
else
{
return "Nothing happening here. Move on."
}
}
}
The "ModuleName.ClassName" sdef tip comes from Swift NSScriptCommand performDefaultImplementation