Archive for October 30, 2025

Thursday, October 30, 2025

Swift 6.2: Subprocess

Holly Borla:

Swift 6.2 introduces a new Subprocess package that offers a streamlined, concurrency‑friendly API for launching and managing external processes.

SF-0007:

The existing Foundation API for spawning a process, NSTask, originated in Objective-C. It was subsequently renamed to Process in Swift. As the language has continued to evolve, Process has not kept up. It lacks support for async/await, makes extensive use of completion handlers, and uses Objective-C exceptions to indicate developer error. This proposal introduces a new package called Subprocess, which addresses the ergonomic shortcomings of Process and enhances the experience of using Swift for scripting and other areas such as server-side development.

It’s currently available as a package, rather than being built into the OS, so the API may not be fully stable, but you can use it on older OS versions.

One of the issues with NSTask/Process is that the simple API works for small amounts of input/output but (unbeknownst to many, even some experts) hangs once you exceed the OS’s buffer size. There are ways around this, but they are awkward (though you can hide them in a helper class). As Christian Tietze (Mastodon) writes:

Helge Heß pointed out that naive usage of Pipe in child Processes can break your program if you pipe too much data.

[…]

If the data is larger than the pipe buffer, you need to drain the corresponding FileHandle with repeated read calls. (Or provide data larger than 64KiB with repeated write calls, respectively.)

If you try to send/receive the whole buffer in one go, from a user’s perspective, your program will freeze, and the read call never return. As a CLI app, it’ll never terminate.

Subprocess seems to be designed to transparently handle this. You can specify the output size limit (and the encoding, if you want a string output), and it will collect the pieces of output as they arrive.

I’ve been using Swift to write scripts, and scripts often need to run shell commands. Unfortunately, Subprocess is currently cumbersome to use for scripting, as Jacob Bartlett writes:

These simple scripts have ludicrous amounts of overhead for what are trivial one-liner operations in the bash shell. Bear with me, because later we’ll look at where Swift subprocess can actually work well, in a more complex workflow.

The additional overhead of requiring a full SwiftPM project, compared to a Bash script, makes it incredibly cumbersome for simple workloads. Also, it’s still not an actual script, so it’ll always require a compilation (and potentially dependency resolution) overhead whenever your code changes.

On the other hand, the syntax, type safety, and composability of Swift code work pretty nicely when you have complex automation workflows to orchestrate, build, and run on demand.

Previously:

NeoFinder 9.0

Norbert Doerner:

New Cataloging engine with more speed and reliability

[…]

Ability to move files to new folders inside a Catalog

Text Replacements for the XMP Editor for faster annotations

[…]

Image Capture to import photos and videos from connected cameras, including adding XMP presets, and store them in a date based folder structure [guide]

[…]

QuickPerson panel to add persons with just a single click

QuickTags panel to add keywords with just a single click

[…]

Multi Renamer has ten more variables to be placed in the new names

NeoFinder (formerly CDFinder) is now 30 years old. The new version is $39.99 to purchase or $25.99 to upgrade.

Previously: