Scripting with Swift

If you are a Swift developer like me, then it is probably no secret that Swift can be used to produce all sorts of things from macOS-, iOS-, iPadOS-, tvOS-, watchOS apps, command line tools, frameworks to system extensions… Well you name it. If it has an Apple engraved on the back, then it can probably run your Swift code.

Christoffer Winterkvist
Fink Oslo
4 min readNov 22, 2022

--

Carles Rabadahttps://unsplash.com/photos/ktWur2xM1hs

Overall, Swift is an awesome bicycle for your mind, except for one thing. It is a compiled language, which means that you need to produce a product or binary to get your code to run.

On the other hand, unix shells like bash, zsh, fish & sh; can run scripts. This can be incredibly powerful because you don’t need to compile, you simply run and it runs for you. Scripts built with any of the mentioned Unix-shells can help you manipulate, customize and automate parts of your workflow which can be a huge timesaver for mundane tasks.

But there are some caveats, you typically need to context switch because it seldom involves the same language that you usually write code in.

I’ve lost count of how many times I’ve had to google: “How to write an if statement in bash”.

Wouldn’t it be great if we could combine the two and leverage Swift’s awesome type system and roaring syntax to write our automations without the need to produce a product?

Just write and run.

It just so happens that this comes baked in using Swift REPL.

So what would scripting with Swift look like?

The first thing we should do is to set up a super simple Swift package.

Sounds like a lot of work, but I assure you, it’s not. We do this to get help from the compiler when we write our script, if we simply open the file using Xcode, it won’t pick up warnings and errors like we are used to.

> mkdir ScriptingWithSwift
> cd ScriptingWithSwift
> touch Package.swift
> touch main.swift

In Package.swift, we can create a barebones package called HelloWorld.

We set the platform to be .macOS and decide which version we wish to be backwards compatible with. To be able to run script inside Xcode, we add an executable target with the same name as the package. We set the path to be an empty string so that it searches for swift files in the root folder.

Let’s do the same for main.swift and keep that super simple for now.

So open the file and add:

Now open the Package.swift with Xcode and run the terminal application.

Before we try to run the script in the terminal, there is one little modification we need to do. We need to give the file an executable attribute.

> chmod +x main.swift

Easy peasy lemon squeezy, now let’s run the script.

> ./main.swift
Hello, world!

Alternativly, you can run it via the swift binary by typing:

swift main.swift
Hello, world!

And voila, now it is off to the races.

If we wanted to, we can execute this script using the built-in app Shortcuts.

  • Open Shortcuts and create a new shortcut.
  • Choose Terminal as the command.
  • Copy-paste the exact path to your script and click run.

This is where I leave you, but before we do, let’s summarize what we have done and end with some inspiration.

To summarise what we have done:

  • We leverage Swift Package Manager to get a sane environment to write our scripts in, which is backed by the all-mighty Swift compiler, right there at your fingertips.
  • We made the script executable from the Terminal or any other application or service that can run scripts
  • Added our freshly brewed script to Shortcuts so that we can have instant access to it and run it at our leisure

So, what can we do with Swift scripting?

Well, it just so happens that with the release of Swift 5.7, you now gain the full force of structured concurrency at the top level which makes it ridiculously easy to fetch information from an API and manipulate the data before processing or presenting it somewhere else.

We can run apple scripts to control UI on macOS or even run other shell scripts or unix commands.

I’ve used it to tweak features in Ventura by changing settings in Stage Manager with the push of a key. You can find more info about that here:

The possibilities are endless.

If you made it to the end and still feel like you came up empty-handed.
Here is a picture of an adorable kitten.

Loan — https://unsplash.com/photos/7AIDE8PrvA0

--

--

Christoffer Winterkvist
Fink Oslo

random hero at @fink-oslo by day, cocoa vigilante by night, dad at dawn. my life is awesome. Previously @hyperoslo