The whole-library scan I thought I'd already fixed
I ran a full review of the Discoverer (Deep Cut Atlas) codebase this week, covering performance, security, and maintainability. One of the findings stung a little. It was a main-actor whole-library scan I was sure I’d already killed.
In an earlier pass, I found spots where the app fetched every album in a user’s Apple Music library and scanned it synchronously on the main actor, freezing the UI on libraries with a few thousand albums. I fixed those. Or so I thought.
This review turned up one more. addAlbumToPlaylist(forTrack:), the function behind the History tab’s “Add album” button, was still doing it. Every tap fetched the whole library and ran a normalize-and-compare over it, right there on the main actor, before adding anything. The earlier fix never reached this write path because it lived in a different function doing a similar looking but distinct job.
The annoying part is that the caller already had the answer. The view model backing that screen keeps a cheap, off-main set of library album keys for exactly this kind of check. It just wasn’t being passed down. The fix was mechanical once I saw it: add a precomputed key set as a parameter and have the caller pass its existing set instead of the service re-fetching from scratch.
While I was in there I found a second problem in the same function. Adding an album’s tracks to a playlist looped a single MusicKit “add one track” call per track. A 20-track album meant 20 sequential network round trips, and if the loop failed partway through, the playlist was left half added with no rollback. MusicKit has a batch edit call that replaces a playlist’s contents in one shot. The app already used it correctly for removing tracks, just not for adding them. Same API, one direction wired right, one direction not.
Both fixes landed in one commit. MusicKit’s local test configuration only loads when running through Xcode’s IDE, not from the command line, so testing meant an actual device pass with Hang Detection turned on: tap the button, confirm there’s no freeze, then open the playlist and count tracks to make sure the atomic write didn’t silently drop anything.
The lesson I keep re-learning is that a pattern doesn’t get fixed once. It gets fixed at each place it shows up, and the tell that you missed one isn’t a crash report. It’s a slow, full read of code you were sure was already fine. Worth doing again every so often.
Related reading
The 8-second scan hiding in every refresh
Measuring on device found a whole-library scan running on every Discover batch - and a 16x measurement trap where the HTTP cache flattered the wrong path.
The mirrored window lied about the phone being unlocked
A one-line grouping fix that was already written, and three walls between it and proof: actor isolation, log stream's Mac-only scope, and a mirrored session that looks unlocked when the device isn't.
Pre-release albums, and the fix I couldn't fully verify
Apple's 'Track N' placeholders rendered as real data. The one detection signal I couldn't confirm became the one signal I stopped depending on.