使 Cocoa 应用程序成为可编写脚本的 Swift [英] Making Cocoa Application Scriptable 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.
这是一个基本示例,在 NSScriptCommand
的 evaluatedArguments
中传递字符串,然后在 Swift 中作为脚本命令的结果返回该字符串(您可以返回命令的成功/失败或任何其他类型的结果的布尔值;实际上,在你的 sdef
中,你说你要返回一个 boolean
但你的命令正在返回一个 string
(sdef
定义中的 text
)).创建您的 sdef
可能很棘手.您的命令代码应以套件代码开头,您可以删除 id
和 optional
参数(如果省略 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.
您可以下载演示项目:
以下是相关部分(除了您在测试中正确的 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屋!