Вызов быстрых методов из AppleScript

Я пытаюсь написать AppleScript, который вызывает мое приложение Swift для получения значения. Метод принимает строку и должен вернуть другую строку.

Вот мой файл.SDF:

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

Соответствующий код Swift довольно прост:

func myCommand(_ command: NSScriptCommand) -> String
{
    if let myParameter = command.evaluatedArguments?["myParameter"] as? String
    {
        return "Hello World!"
    }
    else
    {
        return "Nothing happening here. Move on."
    }
}

и наконец мой AppleScript здесь:

tell application "MyApp"
    set r to my command with "Hello"
end tell

Когда я выполняю AppleScript, он распознает мою команду, но не вызывает код Swift, который я пытался связать с ним. Ни Xcode, ни AppleScript не сообщают о проблеме. Я что-то пропустил или поставил свой код в неправильном месте?

1 ответ

Решение

Для такого рода сценариев я бы порекомендовал подход "сначала команда" (он же глагол первый), а не подход "объект сначала", который вы пытаетесь. Ваш sdef будет выглядеть так (заменив "MyProject" именем вашего проекта, то есть именем модуля Swift вашего приложения):

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

MyCommand класс должен выглядеть так:

class MyCommand : NSScriptCommand {

    override func performDefaultImplementation() -> Any? {
        if let _ = self.evaluatedArguments?["myParameter"] as? String
        {
            return "Hello World!"
        }
        else
        {
            return "Nothing happening here. Move on."
        }

    }
}

Подсказка sdef "ModuleName.ClassName" взята из Swift NSScriptCommand executeDefaultImplementation

Другие вопросы по тегам