使 Cocoa 应用程序成为可编写脚本的 Swift [英] Making Cocoa Application Scriptable Swift

查看:21
本文介绍了使 Cocoa 应用程序成为可编写脚本的 Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使我用 Swift 编写的 Cocoa 应用程序可从 Applescript 编写脚本.

I am trying to make my Cocoa Application that has been written in Swift scriptable from Applescript.

我创建了一个 SDEF 文件,配置了我的 info.plist 并创建了一个我认为合适的类.

I have created a SDEF file, configured my info.plist and created a class which I think is appropriate.

definition.sdef

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">


<dictionary title="SamX">

    <!-- specific suite(s) for the application follow... -->
    <suite name="SamX Scripting Suite" code="Samx" description="Suite for communication with the application">

        <command name="savedoc" code="corecnte" description="description">
            <cocoa class="ProjectName.ScriptingSaveNotification" id="BLah"/>

            <parameter name="with dname" code="WTdc" type="text" optional="no" description="description">
                <cocoa key="DocumentName"/>
            </parameter>

            <result type="boolean" description="The result of the invocation. True if it succeeds, False if it does not"/>
        </command>
    </suite>
</dictionary>

info.plist

ScriptingSaveNotification.swift

import Foundation
import Cocoa

class ScriptingSaveNotification: NSScriptCommand, NSUserNotificationCenterDelegate {

    override func performDefaultImplementation() -> AnyObject? {
        let parms = self.evaluatedArguments
        var name = ""
        if let args = parms {
            if let DocumentName = args["DocumentName"] as? String {
                name = DocumentName
            }
        }


        debugPrint("We were prompted to save");
        return "hello world"
    }

    func userNotificationCenter(center: NSUserNotificationCenter, shouldPresentNotification notification: NSUserNotification) -> Bool {
        debugPrint("We were prompted to save");

        return true
    }
}

我在哪里

我有一个应用程序可以启动.应用程序的 SDEF 文件似乎反映在 Applescript 编辑器中.Applescript 编辑器还返回字典定义.然而,当我运行命令时,我总是得到 5 (int) 的输出,并且我的调试行似乎没有在 Xcode 中输出.

Where I Am

I have an application that launches. The application's SDEF file appears to be reflecting in the Applescript Editor. The Applescript editors also returns a dictionary definition. However when I run the command, I always get an output of 5 (int), and none of my debug lines appears to be outputting in Xcode.

在我看来,我可能在 SDEF 中引用了我的类不正确.但我不是 100% 确定.我试过多次重命名它.任何帮助将不胜感激.

It appears to me that maybe I'm referencing my class in the SDEF improperly. But I'm not 100% sure. I've tried renaming it several times. Any help would be greatly appreciated.

Applescript 字典

测试脚本

tell application "MyApplication"
    set testString to "Hello"
    set returnValue to savedoc testString
    display alert returnValue
end tell

推荐答案

主要问题是您实际上并未在脚本中使用 with dname 参数.应该是:

The main issue is that you don't actually use the with dname parameter in your script. It should be:

set returnValue to savedoc with dname testString

也就是说,以下信息对于创建正确的 sdef 仍然有效,其他建议/示例可能会有所帮助.

That said, the info below is still valid for creating a proper sdef and the other suggestions/examples may be helpful.

这是一个基本示例,在 NSScriptCommandevaluatedArguments 中传递字符串,然后在 Swift 中作为脚本命令的结果返回该字符串(您可以返回命令的成功/失败或任何其他类型的结果的布尔值;实际上,在你的 sdef 中,你说你要返回一个 boolean 但你的命令正在返回一个 string(sdef 定义中的 text)).创建您的 sdef 可能很棘手.您的命令代码应以套件代码开头,您可以删除 idoptional 参数(如果省略 optional 参数,则默认值为参数是必需的).如果您只需要一个参数,您也可以使用 direct-parameter 代替.

This is a basic example of passing a string in the evaluatedArguments of the NSScriptCommand and then returning that string as the result of the script command in Swift (you could return a boolean on success/failure of the command or any other type of result; and, actually, in your sdef you say you're going to return a boolean but your command is returning a string (text in sdef definitions)). Creating your sdef can be tricky. Your command's code should start with the suite's code and you can remove the id and optional parameter (if you omit the optional parameter, the default is that the parameter is required). If you do just need a single parameter you could also just use the direct-parameter instead.

您可以下载演示项目:

ScriptableSwift.zip

以下是相关部分(除了您在测试中正确的 plist 条目之外).

Here are the relevant bits (aside from the plist entries that you have correct in your tests).

ScriptableSwift.sdef

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="ScriptableSwift Terminology">
    <suite name="ScriptableSwift Scripting Suite" code="SSss" description="Standard suite for application communication.">
        <command name="save" code="SSssSave" description="Save something.">
            <cocoa class="ScriptableSwift.SaveScriptCommand"/>
            <parameter name="in" code="Fpat" type="text" description="The file path in which to save the document.">
                <cocoa key="FilePath"/>
            </parameter>
            <result type="text" description="Echoes back the filepath supplied."/>
        </command>
    </suite>
</dictionary>

SaveScriptCommand.swift

import Foundation
import Cocoa

class SaveScriptCommand: NSScriptCommand {
    override func performDefaultImplementation() -> AnyObject? {
        let filePath = self.evaluatedArguments!["FilePath"] as! String
        debugPrint("We were prompted to save something at: \(filePath)");
        return filePath
    }
}

测试 AppleScript

tell application "ScriptableSwift" to save in "path/to/file"

结果:

"path/to/file"

这篇关于使 Cocoa 应用程序成为可编写脚本的 Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆