Estoy creando una aplicación Swift MacOS que interactúa con un dispositivo externo a través del puerto serie. Puedo controlar el dispositivo a través de la aplicación, pero quiero poder controlarlo incluso dentro de otras aplicaciones que usan AppleScript (todo lo que necesito es un método simple como tell application "App" to send "string" ). He buscado en numerosas fuentes y no pude encontrar nada útil.
Tengo cero conocimiento en Obj-C.
Actualizar:
He leído algunos otros tutoriales y tengo la idea. Desafortunadamente, todavía no entiendo cómo hacer un método simple como tell application "App" to send "string" .
Por ejemplo, la aplicación Spotify para Mac tiene esta cadena en su archivo .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> Su aplicación recibe comandos como tell application "Spotify" to play track <track> y los ejecuta. Esto es exactamente lo que quiero.
Desafortunadamente, no tengo idea de cómo manejan este comando en el código principal. Tal vez SPPlayTrackScriptCommand esté implementado de alguna manera.
He leído muchos tutoriales y todavía no puedo encontrar nada sobre esto en particular.
Actualización #2
Eso es lo que he logrado lograr:
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 } }Prueba AppleScript:
tell application "App" send "string" end tellNada funciona y todo lo que obtengo es valor faltante .
Gracias
Entonces, logré hacer exactamente lo que quería después de 4 horas de tediosa investigación.
Aquí está todo el código:
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 } }Prueba AppleScript:
tell application "Noonecares" send command "s" end tell Resulta que App.ScriptableApplicationCommand es esencial. ScriptableApplicationCommand solo no hace nada.
Al menos hoy aprendí algo nuevo.