Sleeping through a decade of Cocoa: Retrospective from modernizing an old Mac app

A few years ago since I started using Macs more often, one annoying thing I dealt with was using my local music library. My usual solution was to just drag files from the file manager to a music player, but this wasn’t as nice on macOS (due to i.e. SMB latency). However, I did have a Subsonic server, which provides a nice music streaming server, complete with an API for clients to use for things like phones. Why not use this on my laptop too?

Of course, if I bought a Mac, I’m not going to put up with bad cross-platform solutions that suck everywhere, when I can instead run bad native software that sucks uniquely for my platform of choice. However, there weren’t too many clients available on Mac. Mostly all of them were unmaintained and had been abandoned in the Snow Leopard era. One of them was Submariner, and it was open-source after the developer (RafaĆ«l Warnault) had stopped working on it. Writing my own seemed a bit daunting with no background, but what if I used the Submariner codebase, and started from there?

Now I’ve been maintaining Submariner for almost two years at this point (it even has a minimal website), adding features and mostly just focusing on modernizing the codebase. It’s been an interesting experience as my first Objective-C/Mac project. A lot of the lessons of modernizing legacy code are universally applicable, but I’ve learned a lot about the specifics of Apple platforms and how they compare. This article aims to be both a retrospective on what I had to learn, what I had to do, and the lessons I took from it, including a comparison of what the development culture is like between platforms.

Continue reading

Restoring images without the futility of Disk Utility

I was trying to put a Mac OS X 10.6 image onto a USB stick to install on another system. To do this, I attempted to do it from a Mac running 13.6 and failed with a message like this when restoring the image to the partition:

Could not validate source - Invalid argument
The operation couldn't be completed. (OSStatus error 22.)

It turns out that Disk Utility is pretty broken at this. What you’re better off doing is using asr. This utility is what Disk Utility does under the covers anyways.

Continue reading

Why Macs don’t have games, or: Why Vulkan or the Game Porting Toolkit isn’t going to save you

Recently, one of Apple’s focuses at the latest WWDC keynote has been gaming. Two important pillars for this are an HLSL to Metal shader compiler, and the Game Porting Toolkit. Both are important, since HLSL is dominant for shaders in the industry, but the GPTK has become popular outside its intended target audience, with many videos with end-users instead of developers using it to try the latest AAA games. This has led to a lot of speculation online about what obstacles exist for game developers looking to port their games to Mac. What challenges actually matter?

(This is a bit of a rougher post, more addressing common points I see from Mac gamers on why they don’t have games. I’m not a game developer or expert in 3D graphics APIs, but I do keep up with the space. There is also some Kremlinology on Apple, but that’s inevitable considering the secrecy.)

Continue reading

Opening System Settings/Preferences to a specific app’s notification settings

If you need to open System Settings (formerly System Preferences) to a specific preference pane, there’s a URL scheme for that. However, some panes seem to take options for opening specific things. In my case, I wanted open the notifications pane to a specific app. The system Maps application can already do this, so I popped it open in a disassembler and learned the secret – ?id=(app bundle ID). For example, opening the following URL will open the notifications settings for Firefox:

x-apple.systempreferences:com.apple.preference.notifications?id=org.mozilla.firefox

Debugging an x86 application in Rosetta for Linux

Rosetta on Linux has been great for me, as someone who switched to an ARM Mac and sometimes develops in a VM. This is because my dayjob often involves debugging a proprietary database driver that only has x86 and PowerPC versions available for Linux, not 64-bit ARM. However, while Rosetta can make it easy to run x86 binaries, it’s not as obvious how to debug them. If you naively try running GDB on your x86 program, you get errors like:

warning: `/lib64/ld-linux-x86-64.so.2': Shared library architecture unknown is not compatible with target architecture aarch64.
warning: `/lib64/ld-linux-x86-64.so.2': Shared library architecture unknown is not compatible with target architecture aarch64.
Warning:
Cannot insert breakpoint -1.
Cannot access memory at address 0x66ec48

This is because you’re attaching to the Rosetta binary, which causes all sorts of confusion for GDB. Turns out, Rosetta does actually have a way to handle this.

Continue reading

Building a static GraphViz for macOS

Note: This is a very old post from 2020 I had sitting in my drafts. I figured I would publish it in case it was useful for someone else. Notably, this predates Apple Silicon, so yo would want to build another version that’s ARM and use lipo to make a universal binary. This is left as an exercise to the reader.

I recently had the need for building GraphViz without any external dependencies other than what comes with macOS, as part of an application calling into it. While on Windows, I used their provided binaries, I was on my own for macOS since I wasn’t willing to ship half of Homebrew with my application. Instead, I took a simpler way.

Continue reading

Fixing files marked as stuck as partially transferred in Finder

Very rough note, but if I don’t write it down, no one else will find it. A friend was dealing with an issue where she interrupted a file transfer of many files and directories to an SMB share on macOS and transferred it via other means. However, macOS thought the files were still in a partially transferred state to be resumed. There was no obvious way to tell Finder that it was OK.

It seems that clearing a file’s extended attributes can clear this out. A quick way to remove all extended attributes from everything in the current directory:

shopt -s globstar
xattr -c **

Be careful with this – you might have files that do need the extended attributes. In this case, it wasn’t needed. Read on for the theory on why this might work and the specific attribute that might be a problem.

Continue reading

Files with accents not showing from an SMB share on macOS

I recently had an issue where some files with accents were showing, but not all of them. If none of them were showing, I might have assumed an encoding issue, but it’s clear something else was at play here. This was pretty annoying when I wanted to play a specific song.

As it turns out, on macOS, it’s almost certainly a Unicode normalization issue, where Apple is (unnecessarily) strict about Unicode. I seem to keep running into these issues on macOS – I first into it trying to notarize a zip file. Luckily, there’s a tool that can handle this for you.

Continue reading

“xcrun altool” not found on macOS

I needed to attempt a notarization of a Mac app (currently still in the middle of that long story), but I wasn’t using Xcode, so I had to run tools manually. Unfortunately, I couldn’t use xcrun altool, as it couldn’t find the command. I had upgraded the version of Xcode I was using, so I guess I had some stale links somewhere. Running xcode-select -r did the trick and fixed it.

Can’t add email accounts in macOS (stuck on final step)

When I tried to add an Exchange account (but it seemed to affect IMAP accounts too) in macOS (I was running High Sierra, but it affects other versions too), from either the Internet Accounts preference pane or Mail.app, it would let would let me add an account right until the final step where it asks what kind of services you want enabled on the account, then the Done/Next button just does nothing. You might get a throbber for a second, but it subsides and does nothing.

There’s a lot of somewhat convulted steps posted on the internet, but the simplest is to just reset your keychain from the Keychain Access application (Application Menu->Preferences, it’s one of the options there) and reboot. You’ll have to enter your passwords again (including iCloud), but I had no trouble adding mail accounts after that.