Apple Music Won't Let Me Remember
January 14, 2026 · 745 words · 4 min read
Last.fm doesn't work, Apple doesn't care, so I built something ugly that does.
I like knowing what I listened to. Not in a data-obsessed, Spotify Wrapped, share-your-personality-as-a-pie-chart way. I just want to look back at a month and remember that I played the same album fourteen times during a rough week at work, or that I discovered a band on a Tuesday evening in November and never stopped. Music is timestamps for me, It marks periods of my life in a way calendars don't. And I just want a record of it.
Apple Music does not want me to have this, so there's no native scrobbling, no listening history export, no API endpoint that says "here's what this guy played". The closest thing is the Recently Played shelf in the app, which holds maybe fifty items before it starts forgetting, and it groups by album rather than individual plays. You can't query it programmatically, you can't export it, and you can't even scroll back far enough to see what you were listening to two weeks ago.
The obvious answer would be Last.fm, I've used it on and off between 2008 and 2015. The problem is that the Apple Music integration is, and has been for years, broken in the cursed way that makes you think it almost works. Scrobbles appear sometimes, other times they don't, or sometimes a song shows up three hours late. I've seen an entire album vanish from my scrobble list. Background playback is unreliable, CarPlay scrobbles are a coin flip, and if your phone locks at the wrong moment the whole thing gives up without showing you a single error. If I end up spending more time in an evening debugging whether my listening data was accurate than I spend actually listening to music, that is a sign that something has gone very wrong.
The Last.fm app on iOS relies on the MPNowPlayingInfoCenter API, which Apple does expose, to their credit, but also doesn't seem to prioritise for third-party use. It works well enough for Spotify because Spotify handles its own scrobbling server-side. Apple Music doesn't, and the system-level hooks that Last.fm depends on are flaky, typical of an API that Apple has no incentive to maintain.
So I built my own thing! It's not pretty, but it mostly works.
The core idea is simple, Apple Music on macOS exposes the current track through a now-playing notification, and you can also pull state from the Music app via osascript. I wrote a small daemon in Swift that polls the player state every few seconds, deduplicates, and logs each play to a local SQLite database. It runs on both my devices and catches everything I play at my desk.
import ScriptingBridge
@objc protocol MusicApplication {
@objc optional var currentTrack: MusicTrack { get }
@objc optional var playerState: Int { get }
}
@objc protocol MusicTrack {
@objc optional var name: String { get }
@objc optional var artist: String { get }
@objc optional var album: String { get }
@objc optional var duration: Double { get }
}
func pollCurrentTrack() -> ScrobbleEntry? {
guard let app = SBApplication(bundleIdentifier: "com.apple.Music") as? MusicApplication,
let track = app.currentTrack,
let state = app.playerState,
state == 0x6B505353 // kMusicPlayerStatePlaying
else { return nil }
return ScrobbleEntry(
artist: track.artist ?? "Unknown",
album: track.album ?? "Unknown",
title: track.name ?? "Unknown",
duration: track.duration ?? 0,
timestamp: Date()
)
}For mobile plays, which is where most of my listening actually happens, I use a Shortcut automation that fires when the Music app opens and logs the current track info to a JSON file in iCloud Drive. It's incredibly clunky, it misses tracks if I skip too fast, and it just straight up doesn't catch songs played through CarPlay. But hey, it captures maybe eighty percent of my phone listening, which is eighty percent more than what I was getting before.
The daemon picks up the iCloud JSON files, deduplicates against what it already has, and merges everything into the same SQLite database. The schema is intentionally boring.
CREATE TABLE scrobbles (
id INTEGER PRIMARY KEY,
artist TEXT NOT NULL,
album TEXT,
title TEXT NOT NULL,
duration_seconds INTEGER,
played_at TIMESTAMP NOT NULL,
source TEXT DEFAULT 'macos',
UNIQUE(artist, title, played_at)
);
CREATE INDEX idx_played_at ON scrobbles(played_at);
CREATE INDEX idx_artist ON scrobbles(artist);I built a tiny web UI with Next.js to browse it, just a timeline view, a top artists breakdown by week and month, and a search. It runs locally on the homelab Mac mini and I can access it over Tailscale when I'm out. Having a personal dashboard for something this niche also scratches my nerdy itch. Also, it loads instantly because it's just my data and a SQLite file.
The whole setup has been running for about two months now. I can already look back at December and see the shape of it. A lot of Stevie Wonder during the first week, then a sudden Rachmaninoff phase that lasted ten days, then a stretch of 80s Pop while shipping a feature at work. That's exactly what I want! I don't care about analytics or insights too much, but if I ever do, I have the data to do it.
Is this a reasonable thing to build? Probably not. If Apple exposed a proper listening history API, or if Last.fm's iOS integration wasn't held together with deprecated routines, none of this would exist. But they don't and it is, so here we are.
It works. It's mine. That's enough.