Jacob’s Tech Tavern

Jacob’s Tech Tavern

My ADHD vs. the AlarmKit API

Under the hood of Apple's latest framework ⏰

Jacob Bartlett's avatar
Jacob Bartlett
Jul 28, 2025

It’s no exaggeration to say that alarms run my life.

Without setting alarms for literally everything, I would be reduced to a gibbering, suppurating, boneless puddle that barely qualifies as a human being. My wife would also leave me*.

*she told me to add this

An actual, unredacted slice of my life

But, wielding my alarms (and a little “confidence”), I’m a 10x superhuman capable of delivering at a Series A startup, raising 2 small children, and growing a nascent blogging business.

So imagine my excitement when Apple announced at WWDC 2025 that they are going to expose system functionality to us mere mortals, enabling us to create timers and alarms of our own accord!

Today, we’re going to look at the new AlarmKit API:

  • First, we’ll learn how AlarmKit works under the hood.

  • Next, we’ll understand how to use it:

    • Authorisation

    • Scheduling alarms

    • Customising alarm UI and sounds

  • Finally, we’re going to build the new CEO of my life: my new, open-source ADHDAlarms app, even more convenient and powerful than the system Clock app. I’m talking:

    • Daily alarms (standup, taking meds)

    • Weekly alarms (putting the bins out, cat flea medicine)

    • Spammy alarms (really annoying tasks you’re putting off, like shaving, or returning a bin to B&Q because it’s the wrong shape. Right, so not to get into it but ChatGPT explained to me that a curved edge is ideal for preventing the bag ripping when taking the bins out, which is by far my biggest pain point, but my wife had already bought the rectangle bin because it’s the same one we had before, and I got quite distracted before I could tell her not to, but now we can’t find the receipt and so now we just have a mildly expensive bin in the hallway that we don’t want and can’t return)

Sorry, what were we talking about again?

Right on. AlarmKit.

This post is pretty long, so it may be cut off in some email clients. Read the full article uninterrupted, on my website.

Read on my website

Live Activity stuff and Dynamic Island malarkey are huge rabbit holes, so I will cover them another time, where I can give Widgets and ActivityKit the love they deserve.

On with the show.


How AlarmKit works under the hood

If you’ve ever suffered from sleep paralysis, AlarmKit is largely powered by the same thing under the hood: Daemons.

Daemons are system programs that run in the background. On iOS, they power core services such as the home screen (SpringBoard), touch & motion events from hardware (backboardd), audio & video playback (mediaserverd), and location services (locationd).

A daemon also powers iOS alarms.

*Since Apple hasn’t given that much detail, I’m making an educated assumptions that the AlarmKit API uses the same underlying framework and daemon as the regular Clock app. Because, uh, of course that’s what they’re doing. I’ll refer to the Clock app here, to help draw a line between guaranteed facts vs speculation.

The basic underlying functionality in the Clock app is provided by MobileTimer.framework. This framework contains the full functionality powering timers and alarms.

When using classdump-dyld or RuntimeBrowser, the full header interface for the alarms can be generated into a header file, Alarm.h.

The interface is very similar to the AlarmKit scheduling parameters we’re going to look at soon, so it’s a fairly clear indication that Clock and AlarmKit are both built on top of this framework. So I think we are okay to use them interchangeably going forward.

The Clock app has a private entitlement, com.apple.private.mobiletimerd, which grants it permissions to communicate with the mobile timer daemon (which itself links and imports MobileTimer.framework). This privileged program runs constantly in the background, monitoring alarms set up by the framework, scheduling them, and triggering them by calling _fireScheduledAlarm().

-(void)_fireScheduledAlarm:(id)
    arg1 firedDate:(id)
    arg2 completionBlock:(/*^block*/ id)arg3;

When fired, the alarm tells SpringBoard to interrupt whatever’s happening, and present the alarm UI.

Alarms have special system privileges:

  • They override silent mode.

  • They use a private AVKit audio session category to ignore muting.

  • They are whitelisted by focus modes like Do Not Disturb or Sleep Focus.

We can learn a lot about private APIs by lurking on Jailbreak forums. The BetterAlarm app demonstrates how it creates an alternative alarm screen interface by hooking into mediaserverd to intercept the alarm playback and presenting an alternative experience from SpringBoard.

Now we have an idea what it’s doing under the hood, let’s look at how to actually use AlarmKit.

Subscribe for free to continue reading

Enter your email and get every post from Jacob’s Tech Tavern.
Already have an account? Sign in
© 2026 Jacob Bartlett · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture