Module verification must be enabled in order for Swift to use the module

Ugh. This was annoying to figure out. If you have a framework target in Xcode with a modulemap – e.g. because you’re wrapping a C or C++ library for use in Swift – you must keep the module verifier enabled (the ENABLE_MODULE_VERIFIER build setting) for that framework, otherwise any Swift targets using that framework won’t… Read more

SwiftUI drag & drop does not support file promises

SwiftUI doesn’t offer anything equivalent to NSFilePromiseProvider, i.e. to write data to the drop destination. You have to ditch SwiftUI and use AppKit’s drag & drop APIs instead. FB13583826. Is that it? I know that’s not a very helpful in some sense, but I wasted days trying to figure out how to implement this very… Read more

Bad API example: FileManager’s url(for:in:appropriateFor:create:)

I find FileManager‘s url(for:in:appropriateFor:create:) to be very unintuitive. It seems to have multiple, largely-orthogonal functions. It can provide paths to common folders (albeit badly). It can create temporary folders. It can locate volume-specific bins (Trash folders). It is an example of bad API design. Specifically, regarding cohesion: the principle that an API should have one… Read more

Creating files safely in Mac apps

Creating a file is a pretty basic and conceptually simple task, that many applications do (whether they realise it or not – library code often does this too, at least for temporary files such as caches or for communicating between programs). So you’d think it’d be trivial to do correctly. Alas, it is not. ☝️… Read more

Downcasting in a for loop

I sometimes forget that this is possible (and even more often exactly what the damn syntax is – kudos to vacawama in today’s case of this for reminding me with their StackOverflow answer). There are numerous other ways to write the above, but I think it is the most elegant. Inferior Alternatives More indentation, and… Read more

SwiftUI main thread hang detector

Illustration of the MacOS Spinning Pinwheel of Death cursor

This is just a little snippet that is quite useful for reporting when your GUI thread (the main thread / actor) hangs for a significant amount of time. There are numerous heavier-weight tools for analysing this sort of thing, but I’ve found that this simple monitor does what I need most of the time. You… Read more

SwiftData pitfalls

I’ve been exploring SwiftData lately, and I’ve been unpleasantly surprised by how many sharp edges it has. I’m going to try to describe some of them here, so that hopefully others can avoid them (or perhaps be dissuaded from using SwiftData to begin with). I’m using Xcode 15.0.1 (Swift 5.9) on macOS 14.1 (Sonoma). Background… Read more