Keyboard Maestro supports Swift?!

Interesting. Pardon my ignorance, but why is this better than just using KM’s Custom HTML Prompt?

Because using JXA, I can:

  1. Interact with other Mac apps
  2. Get and pass data between apps and the OSX
  3. The KM HTML Prompt by itself only allows data to pass between the Prompt and KM variables
  4. I have a complex use case: Merging Evernote Notes, where I need to present the user with a number of options, and using data from Evernote, that I can't easily do just using JXA/AS.
  • So, I get the data from Evernote using JXA
  • Display the data and options using a KM HTML Prompt I called from JXA
  • User's choices are returned in KM vars, which I read using JXA
  • I then execute the merge, using the data and options.

Get the picture? :smile:

You know, I actually have used Basic, sort of — Visual Basic for automating applications.

Yes I do. :slight_smile:

Let me ask a question, and I’m not suggesting this is a better way to do things, I just want to verify my understanding:

Isn’t the flavor of JavaScript used inside a Custom HTML Prompt JXA? Can’t you do all those things with JXA inside the .html script?

Even the merge could be done in the OK button event handler, right? (I shiver as I write that, but as I said, I want to verify my understanding.)

No. All JavaScript in a browser is just core JavaScript, NOT JXA.

JXA adds the bridge to Apple Events, and can do anything the user is authorized to do. As you know, core JavaScript in a Browser is very limited in terms of access outside of the Browser's environment.

Apple combined core JavaScript with the Scripting Bridge to produce JXA.
JXA has all the access that AppleScript does.

1 Like

Isn't the flavor of JavaScript used inside a Custom HTML Prompt JXA?

Technically I guess you might say that the JavaScript flavor / variety is the same (see Safari (SF9) JavaScript here, presumably moving to SF TP in a future release), (they share the Safari debugger)

but the context (set of libraries and objects exposed in the global context) is different.

The JavaScript for Automation global context doesn't contain the Safari browser objects like window, document etc,

but it does contain some additional library objects for Automation, interfacing with ObjC, displaying progress bars, pulling in library code, handling local file paths etc. See the objects at the end of this list, from Automation onwards:

  • Progress
  • ObjC
  • Path
  • Library
  • Ref
  • $
  • Application
  • ObjectSpecifier

I'm not sure what your point is, but it seems that it adds confusion to the question to say they are the same "flavor/variety". OK, I suppose they are are both "apples" in the sense that "delicious" and "rome" are both apples.

Apple has made it very clear that JXA uses the same core JavaScript used in Browsers, but JXA clearly has capability not available to the browser JavaScript.

JXA has full access to all of the browser objects, simply by setting an application object to Safari, or Chrome. From a JXA script, you can execute a core JavaScript script in the browser.

You feel so ? I think it's helpful to understand that while there are many JavaScripts in the wild (ES5, ES6 and a spectrum of positions between, at the moment), Safari JS and JS for Automation are the same JavaScript, but running in different library contexts.

(The great thing about KM is that you can run a couple of simple actions and concretize that by listing out the global contexts, and seeing specifically where they differ)

PS to get an even more concrete sense of the relationship (identical JavaScript, different global contexts), another useful exercise is to compare the results of evaluating the one word script 'this' in the Script Editor, with the result of doing the same on the Safari console line.

In Safari, for example,

  • Choose Develop > Show Error Console
  • enter 'this'
  • Expand disclosure triangle of the global Window object reference that is returned

Many of the objects are shared with the JavaScript for Automation context, others are not.

Yes, I do think so. I'm still confused as to your point.

For most Mac users, I believe the important point is to know that JXA and JavaScript for Browsers are two different languages, with two different uses.

  • JXA -- Used for Mac automation
  • JavaScript for Browsers -- used to control and manipulate web pages

It is very nice that JXA uses the core JavaScript language. That makes it easier for those experienced in browser JavaScript to learn and use the additional features and commands of JXA.

Let me ask you this, then. Swift can be used to create iOS apps, and OS/X apps. The only difference is what libraries (imports) you can use. I discovered this the hard way. You import something like UIKit to get stuff for iOS, and Cocoa to get NSxxx stuff for OS/X.

Same language, or different languages?

I don’t think you need to worry too much if people differ with you on that.

To me a language is a particular syntax, with a parser and code generator for it. Safari JS and Automation JS are the same language in that sense, and they use the same version of the same parser, code generator, debugger.

I find it helpful to know that its the same language (JSC) with some shared libraries and some differing libraries – running in different namespace and pragmatic contexts. No problem if you don’t see it that way. I’m sure we can all agree to differ :slight_smile:

( Probably no urgent need to get into this territory: https://xkcd.com/386/ : - )

Well, it appears that Swift doesn’t really support automating other applications. Not that I can tell, anyway. Certainly not easily, as in AS and JXA. So no way to kme.getvariable or kme.setvariable. That kind of limits its use with KM, I think.

Yes - it looks as if you essentially have to point to an AppleScript file or give an AS code literal to do that from Swift …

Yeah, fun.

I suspect the issue is Swift’s strong typing. I read somewhere that someone was automating iTunes from Swift, and the post said something about needing to import some sort of file, like “itunes.h” or something like that, that apparently has the type definitions for talking to iTunes.

Wonder when they’ll work on that? They probably have their hands full with “more important” things right now.

I think I'll stick with scripting in JSC (and PureScript | Haskell for bigger projects)

One of the advantages of JSC on the Mac is that in addition to the JSA and Safari contexts, you can also use JSC (without either the Automation or Browser library sets) in a shell scripting context, which comes with a few library resources of its own, notably a print() function, where the browser context has Console.log() . Here, for example, using CodeRunner.app

we can list the objects provided in this context:

Good! See you at the finish line. Last one there buys the beers! :grinning:

:slight_smile:

(And of course, the next version of JSC, already in Safari Technology Preview, has good ES6 compliance, with tail recursion optimisation, a lighter lambda syntax etc)

(but my main reservation about Swift is still just that irrational reluctance to spend too much time with something that is essentially single platform)

1 Like

Is this the "JSC" that you refer to:
JavaScriptCore – WebKit

JavaScriptCore - ES5 build in the Automation, SF9, and command line contexts, ES6 build in the Safari TP context