Write SwiftUI command line scripts!

I figured this might be interesting to some folks on the forums: I updated an old script I had demonstrating how to make a command line tool with a SwiftUI UI. It is now much easier with the new SwiftUI App Lifecycle support (its a whopping 20 lines shorter)!

If you create an executable script from the following gist (chmod +x <path-to-script>), you can invoke it like a script to see it in action (this requires your command line tools to be set to Xcode 12).

10 Likes

Instead of using App.main(), could you use the new @main annotation?

No, because command line scripts treat the body of the script as if it were “main.swift”, so synthesizing a main.swift using the annotation creates a conflict. Either way, it would just be one line of code versus another, so not a ton of utility.
That said, we are, benefitting indirectly from the introduction of the @main attribute, because it encouraged the simplification of the architecture to just having a static main method rather than @NSApplicationMain doing a bunch of magic.

4 Likes

This is really powerful. Especially for something like Quick Actions that might need the user to make a choice, or show the output.

I noticed that the window is in the background when it opens. Is there a way to make it focus or come into the foreground by default?

@George: How do you make it read from the terminal interactively?

Thanks for your interest in this! This is pretty old code which could use a dusting off.

I’m sure there is an NSWindow API for programmatically focusing a window, I don’t remember running into this and when I made this my goal was to use the least Lines of code to make this work, which is rarely a good goal. I haven’t tried it but NSApp.activate(ignoringOtherApps: true) seems promising.

The script is a regular Swift program. So you can use any of the mechanisms you would use in a compiled executable. “Interactively” can mean a lot of things, from barebones getchar requests, to repeated invocations of readline. If you want something more advanced or to mixin other command line tools, I would recommend looking at my Shwift library. It’s not yet easy to add SPM dependencies to a script but you might be able to find a way to do what you want in the source.

1 Like