If I have a string variable with JXA source code, is there a way to run that from swift? It seems NSAppleScript only works with AppleScript source.
Asked
Active
Viewed 978 times
2 Answers
7
Here is an example showing how to use OSAKit from Swift to run a JavaScript for Automation script stored in a string:
import OSAKit
let scriptString = "Math.PI";
let script = OSAScript.init(source: scriptString, language: OSALanguage.init(forName: "JavaScript"));
var compileError : NSDictionary?
script.compileAndReturnError(&compileError)
if let compileError = compileError {
print(compileError);
return;
}
var scriptError : NSDictionary?
let result = script.executeAndReturnError(&scriptError)
if let scriptError = scriptError {
print(scriptError);
}
else if let result = result?.stringValue {
print(result)
}
This Swift code was adapted from the Hammerspoon source code (Objective-C).

bacongravy
- 893
- 8
- 13
-5
Why? JXA is a dog in every respect. If you just want to run JS code, the JavaScriptCore Obj-C API is far cleaner and easier. If you want to control "AppleScriptable" applications then use AppleScript—it's the only officially supported† option that works right.
(† There is SwiftAutomation, but Apple haven't bitten and I'm not inclined to support it myself given Apple's chronic mismanagement of Mac Automation. We'll see what happens with WWDC17.)

has
- 92
- 1
-
I already made tons of JXA scripts, so I'd like to be able to execute from Swift. If Swift can't do it, I guess only way is running shell with osascript through swift? – jl303 May 27 '17 at 20:21
-
1There is OSAKit, but it's undocumented so you'll have to figure it out for yourself. Or just save your scripts in `.scpt` format, which `NSAppleScript`/`NSUserAppleScriptTask` will run. (Compiling from source every time is a code-smell in itself; common in naive/unsafe code that parameterizes scripts via code string munging instead of passing them in as parameters to the script's `run` handler.) BTW, another benefit of AppleScript is that AppleScriptObjC to call AS handlers [directly from ObjC/Swift](http://appscript.sourceforge.net/asoc.html) as if they’re native methods; vastly less painful. – has May 28 '17 at 08:35