Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making SwiftUI app Scriptable with AppleScript and Javascript JXA

Please note I have carefully followed How to implement AppleScript support in a Swift MacOS app - however this is not working for me. I assume it's out of date.


After following a variety of documentation, guides, examples, I'm stuck trying to get AppleScript / Javascript support working in a SwiftUI app. (in Macos Big Sur, to begin with.)

The main problem seems to be that all documentation, examples, etc. are out of date.

I could pose this question as being about Swift 5 + AppDelegate instead of SwiftUI and I'd be in the same pickle.

So here's what I have so far...

  • Info.plist - (absent in SwiftUI) added with:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSAppleScriptEnabled</key>
    <true/>
    <key>OSAScriptingDefinition</key>
    <string>Progression.sdef</string>
</dict>
</plist>
  • Progression.entitlements to allow scripting. (Sandbox is switched off too.)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <false/>
    <key>com.apple.security.files.user-selected.read-only</key>
    <true/>
    <key>com.apple.security.automation.apple-events</key>
    <true/>
</dict>
</plist>
  • I've then created what I hope is a working Progression.sdef scripting definition file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="Progression Terminology">
    <suite name="Progression Suite" code="PrgN" description="Progression scripting classes and commands.">
        <command name="progress" code="proGress">
            <cocoa class="Progression.ProgressCommand"/>
        </command>
    </suite>
</dictionary>
  • ProgressCommand in the SwiftUI app.
import Foundation
@objc class ProgressCommand: NSScriptCommand {
    @objc override func performDefaultImplementation() -> Any? {
        print("Called")
        return nil
    }
}
  • I can load the app, and detect the sdef in ScriptEditor > Open Dictionary...
  • In an AppleScript I can call quit on the app (although TBH I haven't tested to see if this works if I pull all the scripting items out.):
tell application "Progression"
  quit
end tell
  • In AppleScript if I call progress it seems to recognize the command, although I'm not sure if it's getting past the .sdef level ... because it fails with:
tell application "Progression"
  progress
end tell
error "Progression got an error: Can’t continue progress." number -1708

At this point I'm stuck for a couple of days.

Edit: I found this answer:

https://stackoverflow.com/a/37202803/311660 although adding the code to the SwiftUI App doesn't work.

Thankfully there is a project & code supplied (using the older NSAppDelegate Style.) which works standalone.

If I can't get a working answer for pure SwiftUI, I'll just re-implement the app using NSAppDelegate, at the end of the day I just need a working link to ApppleScript.

The question remains, is this possible in a SwiftUI app?

like image 614
ocodo Avatar asked Sep 04 '26 09:09

ocodo


1 Answers

So the answer in https://stackoverflow.com/a/37202803/311660 solves this problem, it works fine with SwiftUI.

The problem in my code is the name of my command.

<command name="progress" code="progress">

progress is a reserved word (used for progress indicator), changing it to foobar in my example code, fixes the issue.

This project was built to show how to use SwiftUI with AppleScript.

like image 136
ocodo Avatar answered Sep 06 '26 19:09

ocodo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!