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

A perfect little feature: Universal Clipboard

Apple product photo for Universal Clipboard, showing an iPhone next to a MacBook Pro, with an image selected on the iPhone and 'Copy' highlighted in the pop-up menu, and that same image in a Pages document on the Mac, implying it was just pasted there.

Perhaps in karmic balance of my previous post critical of one of Apple’s APIs, I want to highlight an Apple OS feature that I use every day, that ironically is so simple, obvious, and reliable that I almost never stop to appreciate it. Universal Clipboard basically just means you can copy something on one device… 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