A two-line accessibility fix that needed a real phone to prove
Small fix, annoying path to verify it: the accessibility audit on Deep Cut Atlas turned up a spot where VoiceOver couldn’t tell which playlist was currently linked. The row showing a checkmark next to the linked playlist had no accessibility trait on it - VoiceOver read every row identically, just the playlist name, with no way to know which one was selected. The fix was two lines: track whether the row is linked, then conditionally apply .accessibilityAddTraits(.isSelected). I’d already shipped the identical pattern elsewhere in the app for a filter chip, so this was just copying something known-good.
Here’s the part that took longer than the fix: this screen only populates from a live Apple Music API call, and that API doesn’t work in the iOS Simulator at all. Not “flaky” - it just returns nothing. So the only way to see whether my two-line change actually broke anything was a real, physical iPhone.
I tried to drive the whole thing over Apple’s device-management CLI (devicectl) - build, install, launch, no hands required. It got exactly one step from the finish line: launch failed because the phone was locked. Not a bug, just physics - Apple won’t let you open an app’s UI on a screen nobody’s looking at. That step needed an actual unlock on the actual device.
Once unlocked, I hit a second wall: the screen-mirroring tool for driving taps remotely reported “no window” even though the phone and the app were both fine. Turns out this is a known gap I’d actually diagnosed in an earlier session - the tool only auto-recovers from a “paused” connection, not a “no window” one, because it doesn’t cache the window handle to reattach to. The fix there wasn’t a script, it was restarting the whole tool connection.
Lesson: “verify on device” sounds like one step. In practice it’s a chain - unlock, build, install, launch, reconnect the automation, THEN actually check the thing - and any link failing stops the whole chain, even for a change this small. Small code, real infrastructure.
Related reading
What an accessibility audit found in my own SwiftUI badges
Same-hue text on its own 18%-opacity tint measures at 1.27:1 no matter which color you pick - and the one badge that passed by going bold instead of changing color.
Verifying a fix at an extreme setting found a second bug
The long titles truncated exactly as designed. The one-word badge - the field 'too short to ever need a line limit' - hyphenated itself into 'Al-bum' stacked in a capsule.
I only fixed the screenshot I was asked about, not the ones that were also broken
One recaptured marketing shot looked done - until the deflating question: is this really every screenshot? The other three in the same set were stale too, each in a different way.