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

NSImage is dangerous

Screenshot of an excerpt from Xcode's debug console showing the output of AddressSanitizer, having detected data race involving NSImage.

NSImage is formally documented as largely not thread-safe: The following classes and functions are generally not thread-safe. In most cases, you can use these classes from any thread as long as you use them from only one thread at a time. Check the class documentation for additional details. Apple’s Threading Programming Guide > Appendix A:… Read more

Reminder: macOS system frameworks binaries are hidden (since Big Sur)

Every now and again I’ll go to do something really innocuous with an Apple framework, like disassemble it in Hopper or check the link headers. And every. single. time. I forget that Apple did some really weird shit in Big Sur, and removed the binaries. $ ls -lh /System/Library/Frameworks/AppKit.framework/Versions/Current/AppKit ls: /System/Library/Frameworks/AppKit.framework/Versions/Current/AppKit: No such file or… 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

getifaddrs never specifies broadcast addresses

Apple “Feedback” #12149764. According to man 3 getifaddrs: The ifa_dstaddr field references the destination address on a P2P interface, if one exists, otherwise it contains the broadcast address. In my testing the ifa_dstaddr field is never non-null. I’m not sure I have any suitably configured P2P interfaces, but I definitely have interfaces with broadcast capabilities… Read more

getifaddrs returns truncated sockaddr_in’s for AF_INET ifa_netmasks

Apple “Feedback” #12149675. Some netmasks returned by getifaddrs have family of AF_INET yet a length less than sizeof(sockaddr_in), e.g. 5, 6, 7, or 8. On macOS Ventura 13.3.1, at least. It looks like it’s actually allocating only eight bytes for the ifa_netmask (not the 16 that is the size of sockaddr_in per MacOSX13.3.sdk/usr/include/netinet/in.h), as it… Read more