SwiftAppleScriptBridge — using AppleScript in Swift, without the ceremony

Hi!

I’ve just published a small open-source package I’ve been using in my own macOS apps, and I thought this crowd might find it useful. I coded this myself a while back, and recently used Claude AI to make it into a public package with documentation and examples.

The short version: it lets a Swift app run AppleScript, pass values into it, and get typed values back. I kept needing this for apps that drive other apps — Adobe InDesign, mostly — and I couldn’t find anything that worked the way I wanted, so I wrote my own and have been using it for a while now.

AppleScriptObjC is good and I’m not trying to replace it. I just wanted direct interaction between the two languages with no middleman, and easy conversion of the common types — strings, integers, reals, booleans, lists and records — in both directions.

You write your script with $placeholders and fill them from Swift:

let countOpenWindows = AppleScriptBridge.AppleScriptObject(
    name: "countOpenWindows",
    returnType: .int,
    script: """
        tell application id "com.apple.finder"
            return count of windows
        end tell
    """
)

let count = try AppleScriptBridge.executeAppleScript(countOpenWindows) as? Int ?? 0

Two things it handles that are tedious by hand: first, every string substituted into a script is escaped, so a file named My “best” shot.jpg doesn’t break your script — or worse, inject into it. Second, you declare what the script returns and get a parsed Swift value back rather than picking apart a descriptor yourself.

Where it’s actually been worth it for me is speed. If you keep the logic in Swift and use AppleScript only to tell the other app to do the things that only AppleScript can do — no list building, no calculations, one task per script — it’s dramatically faster than the equivalent all-AppleScript solution. You also get documentation on hover and autocompletion for your scripts in Xcode, which is absent in Script Editor.

One thing worth knowing up front: an app using this can’t be sandboxed, so it can’t go on the Mac App Store. That’s Apple events in general, not something specific to my package. Developer ID signing and notarization work normally, so direct distribution is fine.

macOS 13+, no dependencies, MIT licensed:

It’s version 1.0.0, so I’d genuinely appreciate people kicking the tyres. If you hit something odd, or there’s an obvious thing I’ve missed from the perspective of someone who lives in AppleScript rather than Swift, tell me — issues and PRs welcome, and so are replies here.

Tx!
Fred