Search code examples
swiftmacosapplescript

Running AppleScript from Swift not working


I'm making a simple menubar app to do some actions such as toggling dark mode in Mojave

Writing an AppleScript for it is fine and when it works 100% when directly running the script. In order to implement it into a menu bar app, I tried searching online and the only answer I found was in this link: Can you execute an Applescript script from a Swift Application

However, when I tried the first solution, I got an error in the console saying:

script: /Users/username/Documents/myscript.scpt: Operation not permitted

My code looked like this:

let proc = Process()
proc.launchPath = "/usr/bin/script"
proc.arguments = ["/Users/username/Documents/myscript.scpt"]
proc.launch()

I've tried another solution, which this time uses NSAppleScript:

let myAppleScript = "tell application \"System Events\" \ntell appearance preferences to set dark mode to not dark mode \nend tell"
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(&error) {
        print(output.stringValue)
    } else if (error != nil) {
        print("error: \(error)")
    }
}

However this time I get an error saying:

error: Optional({
    NSAppleScriptErrorAppName = "System Events";
    NSAppleScriptErrorBriefMessage = "Application isn\U2019t running.";
    NSAppleScriptErrorMessage = "System Events got an error: Application isn\U2019t running.";
    NSAppleScriptErrorNumber = "-600";
    NSAppleScriptErrorRange = "NSRange: {86, 9}";
})

But if I change the script to something simpler, such as "display notification \"test\"", the second solution works perfectly.

This means that the second solution runs AppleScripts fine, but it can't seem to call System Events. How do I fix this?


Solution

  • This error occurs if the application is sandboxed.

    You have two options:

    1. Add the com.apple.security.temporary-exception.apple-events entitlement for System Events
    2. Put the script in the Application Scripts folder of the application and run it from there with NSUserAppleScriptTask