如何在 Swift MacOS 应用程序中实现 AppleScript 支持
How to implement AppleScript support in a Swift MacOS app
我正在制作一个 Swift MacOS 应用程序,它通过串行端口与外部设备交互。我可以通过该应用程序控制设备,但我希望即使在其他使用 AppleScript 的应用程序中也能控制它(我只需要 一个 简单方法,如 tell application "App" to send "string"
)。我搜索了大量资源,但找不到任何有用的信息。
我对 Obj-C 的了解为零。
更新:
我已经阅读了其他一些教程并且有点明白了。不幸的是,我仍然不明白如何制作 one 像 tell application "App" to send "string"
这样简单的方法。
例如。 Spotify Mac 应用在其 .sdef 文件中包含此字符串:
<command name="play track" code="spfyPCtx" description="Start playback of a track.">
<access-group identifier="com.spotify.playback"/>
<cocoa class="SPPlayTrackScriptCommand"/>
<direct-parameter description="the URI of the track to play" type="text"/>
</command>
他们的应用程序接收 tell application "Spotify" to play track <track>
之类的命令并执行它们。这正是我想要的。
不幸的是,我不知道他们如何在主代码中处理这个命令。也许 SPPlayTrackScriptCommand
以某种方式实现。
我已经阅读了很多教程,但仍然找不到关于这件事的任何信息。
更新#2
这就是我设法实现的目标:
Scriptable.sdef:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="App Scripting Terminology">
<suite name="Scriptable App Suite" code="ScNo" description="Scriptable App suite.">
<command name="send" code="SeNdtext">
<access-group identifier="*"/>
<direct-parameter description="Command to send" type="text" requires-access="r">
<cocoa key="commandFlag"/>
</direct-parameter>
<result type="boolean" description="Did it do?"/>
</command>
<class name="application" code="capp" description="The application's basic scripting object.">
<cocoa class="ScriptableApplication"/>
<responds-to command="send">
<cocoa method="send:"/>
</responds-to>
</class>
</suite>
</dictionary>
ScriptableApp.swift:
@objc(ScriptableApplication) class ScriptableApplication: NSObject {
func send(_ command: NSScriptCommand) -> Bool {
//let commandFlag = command.evaluatedArguments?["commandFlag"] as? String
print("A")
return true
}
}
测试 AppleScript:
tell application "App"
send "string"
end tell
没有任何效果,我得到的只是缺失值。
谢谢
所以,经过 4 小时的繁琐研究,我成功地完成了我想做的事情。
所有代码如下:
Scriptable.sdef:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="App Scripting Terminology">
<suite name="Scriptable App Suite" code="NoSu" description="Scriptable App suite.">
<command name="send" code="NoOnSend">
<cocoa class="App.ScriptableApplicationCommand"/>
<access-group identifier="*"/>
<parameter code="NoCm" name="command" description="Command to send" type="text">
<cocoa key="commandFlag"/>
</parameter>
<result type="text" description="ACK"/>
</command>
</suite>
</dictionary>
ScriptableCommand.swift:
import Foundation
import Cocoa
class ScriptableApplicationCommand: NSScriptCommand {
override func performDefaultImplementation() -> Any? {
let text = self.evaluatedArguments!["commandFlag"] as! String
print(text)
return text
}
}
测试 AppleScript:
tell application "Noonecares"
send command "s"
end tell
原来 App.ScriptableApplicationCommand
是必不可少的。 ScriptableApplicationCommand
一个人什么也做不了。
至少今天我学到了一些新东西。
我正在制作一个 Swift MacOS 应用程序,它通过串行端口与外部设备交互。我可以通过该应用程序控制设备,但我希望即使在其他使用 AppleScript 的应用程序中也能控制它(我只需要 一个 简单方法,如 tell application "App" to send "string"
)。我搜索了大量资源,但找不到任何有用的信息。
我对 Obj-C 的了解为零。
更新:
我已经阅读了其他一些教程并且有点明白了。不幸的是,我仍然不明白如何制作 one 像 tell application "App" to send "string"
这样简单的方法。
例如。 Spotify Mac 应用在其 .sdef 文件中包含此字符串:
<command name="play track" code="spfyPCtx" description="Start playback of a track.">
<access-group identifier="com.spotify.playback"/>
<cocoa class="SPPlayTrackScriptCommand"/>
<direct-parameter description="the URI of the track to play" type="text"/>
</command>
他们的应用程序接收 tell application "Spotify" to play track <track>
之类的命令并执行它们。这正是我想要的。
不幸的是,我不知道他们如何在主代码中处理这个命令。也许 SPPlayTrackScriptCommand
以某种方式实现。
我已经阅读了很多教程,但仍然找不到关于这件事的任何信息。
更新#2
这就是我设法实现的目标:
Scriptable.sdef:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="App Scripting Terminology">
<suite name="Scriptable App Suite" code="ScNo" description="Scriptable App suite.">
<command name="send" code="SeNdtext">
<access-group identifier="*"/>
<direct-parameter description="Command to send" type="text" requires-access="r">
<cocoa key="commandFlag"/>
</direct-parameter>
<result type="boolean" description="Did it do?"/>
</command>
<class name="application" code="capp" description="The application's basic scripting object.">
<cocoa class="ScriptableApplication"/>
<responds-to command="send">
<cocoa method="send:"/>
</responds-to>
</class>
</suite>
</dictionary>
ScriptableApp.swift:
@objc(ScriptableApplication) class ScriptableApplication: NSObject {
func send(_ command: NSScriptCommand) -> Bool {
//let commandFlag = command.evaluatedArguments?["commandFlag"] as? String
print("A")
return true
}
}
测试 AppleScript:
tell application "App"
send "string"
end tell
没有任何效果,我得到的只是缺失值。
谢谢
所以,经过 4 小时的繁琐研究,我成功地完成了我想做的事情。
所有代码如下:
Scriptable.sdef:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="App Scripting Terminology">
<suite name="Scriptable App Suite" code="NoSu" description="Scriptable App suite.">
<command name="send" code="NoOnSend">
<cocoa class="App.ScriptableApplicationCommand"/>
<access-group identifier="*"/>
<parameter code="NoCm" name="command" description="Command to send" type="text">
<cocoa key="commandFlag"/>
</parameter>
<result type="text" description="ACK"/>
</command>
</suite>
</dictionary>
ScriptableCommand.swift:
import Foundation
import Cocoa
class ScriptableApplicationCommand: NSScriptCommand {
override func performDefaultImplementation() -> Any? {
let text = self.evaluatedArguments!["commandFlag"] as! String
print(text)
return text
}
}
测试 AppleScript:
tell application "Noonecares"
send command "s"
end tell
原来 App.ScriptableApplicationCommand
是必不可少的。 ScriptableApplicationCommand
一个人什么也做不了。
至少今天我学到了一些新东西。