Return progress from AppleScript (for progress bar)

Is there a way for the Xojo app to receive multiple returns from an AppleScript to drive a progress bar? It seems that as soon as the first return is received the connection is closed. Searched forum and web but (apparently) no cigar. Thank you for any direction you can provide.

Nope.

You can call the script several times.

Eric, thank you for succinctly confirming my fears :grinning:
Michel, thank you for your thoughts. My script is long and takes minutes to run so I couldn’t figure out how to get the progress of running it once by calling it multiple times. I’m probably missing something.

My workaround:
1) AppleScript writes to a text file at the end of every loop
2) Xojo app repeatedly reads that text file, converts to integer
3) app uses integer to drive progress bar

Not as elegant as I might have liked but it seems to work.

Another idea is to write progress output to a Named Pipe and read that from within Xojo. I couldn’t find a complete solution but here are some links to get you started:

Thanks Mike. Looks like this might be batting above my average but I’ll dive in anyway. I’m intrigued. I appreciate it.

Wait, maybe I misunderstood. How are you running the AppleScript? Sounds like you’re launching it as an app, which will work, as you’ve discovered - my “No.” was referring to the scenario when you include the AppleScript in your Xojo project and call it from code.

Can’t you write “your script” in Xojo ?

I stopped using AppleScript because AppleScript is slow, very slow. Depending on what your script do, you may use Xojo to do that far faster… probably.

AppleScript is slow and frustrating and I curse it daily but its superpower is that you can control multiple scriptable apps at the same time - and in concert. That’s magical to me. AS particularly sucks when it comes to things like the UI and that (among other things) is what I’m hoping to use Xojo for. I like it better than Swift or ASObjC. But I’m just a hobbyist so take what I say with a grain of salt.

Thanks Eric. You were right. I’m calling from code and apparently there is no way to receive multiple returns from a single script called once. Thank you.

There’s also the possibility to write your Xojo app with AppleEvents rather than scripts; that’s what I usually do.
Every command you send in your script can be “converted” to its AppleEvent equivalent. Then showing the progress is straightforward, as your Xojo app calls each bit of what was in the script (and can update the progress between the calls).

Yes - AppleScripts are run synchronously on the main thread. All Xojo code stops until the AS returns.

You could look into using the shell command “osascript” in an asychronous shell. That would allow Xojo to continue while the script executes and returns progress info.

Thank you Arnaud and Eric. While converting my current project might not be practical I’m very interested to start writing AppleEvents in Xojo/osascript via shell commands.

Again, thank you all for being so helpful.

Unless your AppleScript is trivial - for example, one or two commands - I wouldn’t bother converting it to Apple Events. They’re much more difficult to understand and maintain, and don’t take advantage of a big chunk of the data conversion AppleScript silently handles behind the scenes.

Furthermore, Apple Events are not faster than AppleScript in any appreciable way and Xojo’s Apple Event support is poor in many ways. I’d suggest you keep up using the scripts you already have.

You can use the ‘osascript’ command to launch and run a compiled AppleScript (which does not need to be an application, just a script that has been saved as Compiled instead of Plain Text) just as though you had loaded it into the Script Editor and pressed Run. You can also pass parameters to ‘osascript’ that will be handed to your script as parameters to the run() handler, just like calling an AppleScript from Xojo.

Another nice thing about this approach is that you can edit the scripts while your app is running and the changes will be executed the next time it is called via ‘osascript’. That’s because ‘osascript’ reads the script file every time you run it. This is a great debugging feature.

OK, I tacked together a quick demonstration. Here’s the script:

on run
	set looper to 1
	repeat
		log looper
		
		set looper to looper + 1
		
		delay 1
	end repeat
end run

Drop that text into a Script Editor document and save the script as a Script. Then, use the ‘osascript’ command to execute it in a Terminal window:

osascript /path/to/script.scpt

The script will run and report 1, 2, 3… etc. until you stop it. If you run the ‘osascript’ command from an Xojo Shell with Mode=Asynchronous, you’ll get the numbers one at a time, with a 1 second delay, in the Shell.DataAvailable event.

This should give you exactly what you need to have your script report ongoing progress. Note that the AppleScript ‘log’ command only works when running in the Terminal - you won’t see any output when running in the Script Editor.

1 Like

Eric, that is brilliant! Absolutely perfect and worked like a charm. I really do appreciate you taking the time to do this. I was patting myself on the back for my little workaround but this is so much more elegant and less prone to error. I love stuff like this. So thank you again.

Eric, thanks for the insights on AppleScript-to-Apple Events conversion. Yes, my AS is pretty long and AE looked beyond me at first glance. So I’m all over the ‘osascript’ command.