Async AppleScript and SwiftUI

Here is a quick demo of how to integrate AppleScript synchronous and asynchronous execution into a SwiftUI application.

The AppleScriptRunner class has an observable property, state, which reports the execution state of the associated AppleScript script. To use AppleScriptRunner, first create an @ObservedObject variable in your SwiftUI view:

	@ObservedObject var script: AppleScriptRunner("""
property counter: 0

set counter to counter + 1
return counter
""")

To run the script, AppleScriptRunner provides two functions: executeSync (run script on the main thread) and executeAsync (run the script in a background thread). You can call one of these functions from a SwiftUI button:

            Button("Run") {
                script.executeAsync()
            }

Then, in your view you can declare content depending on the script’s state:

            switch script.state {
            case .running:
                // indicate the script is running...
                Text("Running...")

            case .complete(let result):
                // Show the result of the script...
                Text("\(result)") // result is an NSAppleEventDescriptor
                    .foregroundColor(.green)
                
            case .error(let error):
                // Show the runtime error
                Text(error.message)
                    .foregroundColor(.red)

            case .idle:
                // The script has never been run...
                Group() {} // empty ...
            }

For the purposes of this demo the AppleScriptRunner class is simplistic in that it only accepts AppleScript source code through its constructor. Obvious improvements include loading compiled scripts, changing the script, etc.

Like what I see. How far are you planning to go with this?

I don’t have specific plans at present. As I’ve done with iOS Shortcuts/AppleScript integration in the past, I’m just trying to show what’s possible.

That said, I think the AppleScriptRunner object probably needs to become a Swift Package that people can easily import into their projects. It can then become more fully featured. More examples always help too.

I’m personally planning to use AppleScriptRunner and SwiftUI in a future Script Debugger feature.

Pull requests are welcome. If you develop another example or expand AppleScriptRunner in some cool way you welcome to contribute.

1 Like