Command Line Swift

In this series we will explore the world of making command line apps in Swift. We'll see how to leverage Swift Package Manager to bring in useful dependencies, how to parse command line arguments, and how to work with files and sub processes.

Length: about 1 hour.

Start Series


1. Command Line Apps In Swift - Parsing Arguments

Subscribers only

I use a collection of command line scripts that help me in the production of NSScreencast episodes. Most are written in Ruby, which is a language I know and love, and some are written in bash, which is... a language. I sometimes wonder what these scripts would look like if I were to write them in Swift. So in this new series I'm going to explore rewriting a script that I use to encode videos using Swift. In this episode we'll bring in the excellent Swift Argument Parser library and use it to give us a clean and consistent command line interface to start with.

2. Working with Files

Subscribers only

Working with files and folders with FileManager is cumbersome. Instead we'll lean on the excellent Files package from John Sundell.

3. Executing Shell Commands

Subscribers only

In this episode we will launch other programs as sub processes and show how to capture its output.

4. ANSI Colors in Command Line Output

Subscribers only

I always like it when command line programs offer colored output, which helps to discern between various stages of output, highlight errors and other important information. This is done with ANSI color codes, which are a somewhat archaic technique, but we can implement a nice wrapper to make it easy to work with in Swift.

5. Handling Long Running Tasks

Subscribers only

When dealing with long running tasks it would be nice to be able to gather output as the task runs and not hang until the entire process is done. In this episode we will extract some useful information out of ffprobe, so we can get the total number of frames in a video file, and then kick off ffmpeg to encode the video. We'll use the Subprocess package to provide a simpler interface over gathering output from a pipe as it is sent, rather than waiting for the end.