PillBox · Support · Troubleshooting

Live Activity & Dynamic Island limitations

Why the lock-screen Live Activity and Dynamic Island can show stale info or not appear — an iOS best-effort limitation — while notifications stay reliable, plus the decision we've taken and the server-backed fix we may offer as opt-in later.

In short: the lock-screen Live Activity and the Dynamic Island are refreshed by iOS on a "best-effort" basis, so they can occasionally show stale information — or not appear at all — until you next open the app. This is a known limitation of how iOS works, not a fault in your data. Your reminders are unaffected: notifications always fire on time, and you can mark a dose Taken or Skip straight from a notification by pressing and holding it. After weighing the available fixes, we have made a deliberate, informed decision to accept this limitation for now rather than add the one thing that would remove it — an external server. This article explains exactly what happens, why, what a fix would involve, and the decision we've taken.

The decision, up front

PillBox is a fully on-device app: no account, no server, and none of your data leaves your phone. The only reliable way to make Live Activities update perfectly in the background would be to introduce a small external server (explained in detail further down). We have decided not to do that for now, and to accept the occasional Live Activity glitch as a known limitation.

We're stating this at the top because we'd rather you understand precisely how the app behaves — and why — than be surprised by it. The part that actually matters for not missing a dose, your reminders, is completely reliable regardless.

What you might notice (in plain terms)

A Live Activity is the card that appears at the bottom of your lock screen for an upcoming dose — the medication name, dose details, a live countdown, and Taken / Skip buttons you can tap without unlocking. On iPhones with a Dynamic Island, the same countdown also appears in the pill-shaped area at the top of the screen.

Two things can happen:

  1. The countdown keeps running, but the wording and colour don't catch up. When a dose passes its due time, the Live Activity is meant to switch from a calm "Due in…" to a red Overdue. Sometimes the number keeps ticking upward correctly, but the label stays on "Due in" and never turns red — until you next open the app, at which point it corrects instantly.

  2. The Live Activity doesn't appear until you open the app. First thing in the morning especially, the lock-screen card for the day's first dose may not show up until you've opened PillBox once. The reminder notification still arrives on time — only the Live Activity is missing.

Both come down to the same cause.

Why this happens

iOS does not let an app freely redraw its lock-screen or Dynamic Island content whenever it likes. Instead, the system refreshes these surfaces on its own schedule, on a best-effort basis — and it will not run the app's display logic in the background at the exact moment a dose becomes overdue.

There's a subtle twist that explains the "the number moves but the colour doesn't" behaviour: the countdown number itself is drawn by iOS, so it keeps ticking on its own. But the decisions around it — the word "Overdue", the red colour — are worked out by PillBox's code, and that code only runs when iOS chooses to refresh the card. Until then, the number moves while everything around it stays frozen on the last thing PillBox was allowed to draw.

Starting a Live Activity has the same constraint. iOS only allows an app to start a Live Activity while the app is open in the foreground (or via a server push — see below). A background task is not permitted to start one. So the morning's first card can't appear by itself; opening the app starts it.

The evidence

In the screenshot below, the dose has already passed its due time. The home-screen widgets have correctly turned red and say Overdue — but the Dynamic Island at the very top still reads "in 0:50", counting as though the dose were still upcoming. Same dose, same moment, two surfaces disagreeing: the number is live, the styling is stale.

Home screen showing a PillBox Dynamic Island at the top reading "in 0:50" while two PillBox widgets below — a small and a medium — both show the same Amoxicillin dose as red Overdue with "50 sec" elapsed and Take/Skip buttons. The widgets have refreshed correctly; the Dynamic Island has not.
The widgets show the dose is overdue (red); the Dynamic Island still reads "in…". The countdown is correct, but iOS hasn't refreshed the label and colour.

The same thing on the lock screen: the Live Activity's counter has run past the due time, yet the card still reads "Due in" and hasn't turned red. The Time-Sensitive reminder notification beneath it, however, fired exactly on time.

Lock screen showing an Amoxicillin Live Activity card with a live counter and Taken/Skip buttons still labelled "Due in", above a Time-Sensitive reminder notification for the same dose that has just fired on time.
The Live Activity counter has passed the due time but the card still says "Due in". The reminder notification below it fired reliably, on schedule.

You'll notice the widgets behave correctly in the first shot. That's not luck — see the technical section for why widgets can do something Live Activities can't.

Your reminders are not affected

This is the important part. The limitation is cosmetic — it affects how the Live Activity looks, not whether you're reminded. Notifications always fire on time, in the background, whether or not the app has been opened.

And you don't need the Live Activity's buttons to act on a dose. Press and hold (long-press) the reminder notification and the same Taken and Skip actions appear. You can resolve the dose right there — no unlocking, no opening the app.

A PillBox reminder notification that has been pressed and held, expanded to reveal Taken and Skip action buttons directly beneath the medication details.
Press and hold any PillBox reminder to reveal Taken and Skip — the same one-tap actions as the Live Activity, always available.

The technical detail (for the curious — and the sceptical)

We've written this section so that anyone with iOS development knowledge — or an AI assistant asked to check our reasoning — can verify that the explanation above is accurate and that the decision is soundly reasoned. Everything here is checkable against Apple's public developer documentation.

How Live Activities render. A Live Activity's lock-screen and Dynamic Island UI is produced by a WidgetKit / ActivityKit extension. iOS re-runs that view code only at specific moments: when the app calls Activity.update(_:), or — on a best-effort basis — when the content passes a staleDate the app sets. Between those moments iOS keeps auto-updating any date/time text drawn with Text(_, style: .timer) / .relative, which is why the countdown keeps moving on its own. It does not re-evaluate the rest of the view (the "Overdue" label, the colour) in the background. PillBox already sets staleDate to each dose's due time to request a refresh at that instant, but Apple explicitly documents this as best-effort, and on a locked, idle phone it frequently doesn't fire — which is exactly what the screenshots show.

Why the widgets get it right. Home-screen widgets use a different mechanism: a WidgetKit timeline, where the app hands iOS a set of future dated entries in advance. iOS renders each entry at its scheduled time, so the widget flips to "Overdue" reliably at the due minute. Live Activities have no equivalent "schedule future content" API. Their only reliable remote trigger is a push.

Why starting needs the foreground. Apple permits Activity.request() (starting a Live Activity) only from the foreground, or from the background via ActivityKit push-to-start over the Apple Push Notification service (APNs), added in iOS 17.2. A background refresh task (BGAppRefreshTask) is not allowed to start one — and in any case fires at a time of iOS's choosing rather than at a precise minute. We confirmed this behaviour on a physical device.

The only reliable fix, and what it would cost. To make Live Activities appear and update reliably in the background, iOS requires a server that sends an ActivityKit push via APNs — one push to start the card at the right time, and one to update it to "Overdue" when the dose passes. There is no client-scheduled push: APNs delivers a push when the sender sends it, and the phone can't send one to itself while asleep, so a small server with a clock is unavoidable.

Crucially, that server would need very little about you:

  • A device push token — an opaque identifier Apple issues for the device. It is not your name, email, or any account (PillBox has none of those).
  • The timing of your doses — when to send a wake-up, e.g. 08:00 and 20:00 — so it knows when to push.

It would not need the content of your doses. The medication name, strength, and quantity can stay entirely on your phone: the push can carry only an anonymous reference, and PillBox's on-device code fills in the real details from local storage when it draws the card. So even with a server, what you take never leaves your device — only an anonymous device token and the times to nudge it.

That is still more than PillBox collects today (which is nothing), and for a medication app even "this device has events at these times" is sensitive information. That trade-off is precisely why this is a deliberate decision rather than an automatic one.

The decision, and what could change

For now, we have decided to accept this limitation. Notifications carry the reliable reminder; the home-screen widgets show accurate, always-refreshed status; and the Live Activity is treated as a helpful bonus rather than a guaranteed surface. For an app that keeps all of your data on your own phone, we think that's the right balance.

We may, in future, offer the server-backed version described above to make Live Activities fully reliable. If we ever do:

  • It will be strictly opt-in — off by default, and never enabled for anyone without their explicit choice.
  • It will be a setting you control, which you can switch on or off at any time.
  • It will not be rolled out across all users or all devices automatically.

To be clear: this is not currently being developed. It is documented here so that the decision — and the reasoning behind it — is transparent and on the record.