Background Health Store Access for Lock Screen Widgets

It's fairly well know and stated that the Apple Health / HealthKit data store is unavailable when iPhone is locked.

Since Lock Screen Widgets were introduced there's been a feature parity mismatch with Apple's own Fitness app which is able to display updating Activity Rings on the Lock Screen. Third party apps cannot do this and have to rely unlocking their device to then trigger an update. This means they often display stale and wrong Health data.

With the release of iOS 18 beta, I see no changes to this... Is there anything I've missed?

Currently for requesting the Timeline Updates on my Widget I have to just keep requesting updates as often as possible and hope that each time the iPhone might be unlocked.... This is inefficient and a waste of device resources. Even a Widget timeline reload API that let the developer say "Only call update if iPhone unlocked" would be useful.

I've asked Apple Support this question about 1,5 year ago and what you would need to do is:

  1. Add the "Data Protection" capability to the main app (so not the Widget extension)
  2. Add “com.apple.developer.default-data-protection” entitlement key with value “NSFileProtectionComplete” to the widget target.

That way the widget will only request new timelines when the data is available (not protected) and you’ll no longer get errors.

If a reload of data would be requested when the device is locked, it will be executed when the device unlocks. Just like Apple's activity rings Lock Screen Widget.

Hope this helps and is what you're looking for!

@Thuri88 This looks like a fantastic suggestion, Thank You!

I'll go ahead and implement this and do some testing.

You mention Apple's activity rings Lock Screen widget implementing this.... I'm fairly sure I've observed it updating throughout the day without the iPhone being unlocked at all. There's also then the problem of StandBy mode and Widget on Mac which also can't update whilst your iPhone is locked.... and lots of my users would love to see their Health data in widgets on their Mac.

I've filed a feedback again on this: FB13879739

🙏🙏 A solution may be offered one day.

Hope it helped and got you (partially) what you’re looking for! I’m not sure you can always show and update the Health data whether the device is locked or not. As far as I know and understood the HealthKit database is locked when the device is locked.

You could show a cached version of your latest data. That way you at least show something, unlocking the device will often update it. Still not a 100% what you’re looking for I guess, so if you do find a solution please let me know! :)

I don't have a way around the locked-store restriction either. There's now an explicit DTS answer confirming reads aren't permitted while locked (thread 824819, May 2026), so I've stopped hoping for one.

What I can offer is the failure mode I hit while working around it, because it's easy to ship by accident and it presents as a completely different bug.

A statistics query that fails because the store is encrypted reports no sum. That is the same thing it reports for a day with genuinely no samples. So if your read does something like

result?.sumQuantity()?.doubleValue(for: unit) ?? 0

and binds the error parameter to _, a failed read returns a confident 0. Mine then got published to the widget with a current timestamp, so every morning the widget showed a plausible, freshly-stamped, completely wrong zero until the app was next opened. It reads exactly like a refresh bug — I lost time on timeline reloads and App Group configuration before noticing the timestamp was fresh, which meant the data wasn't stale, it was freshly wrong.

What worked, given we can't read while locked:

  • Return an optional from the read. nil for a failed query, and 0 only for HKError.errorNoData, which is HealthKit's way of saying the range really is empty.

  • On failure, publish nothing and leave the previous values untouched. A widget showing yesterday's number is far better than one showing a wrong number today.

  • Audit every path that writes to the widget, not just the one you fixed. A freshly-initialized model object is full of zeros too, and those are every bit as plausible as the ones a failed query produces.

  • Carry the day the numbers describe separately from the "updated at" time. Once a write can be skipped, "when was this written" stops answering "which day is this about" — and that distinction is what lets you render a stale payload as visibly stale instead of asserting it.

None of that gets data while locked. It does stop the lock from producing wrong data, which in my case was the actual user-visible bug.

Longer version: https://mcmizzle.com/blog/healthkit-widget-shows-zero/

Background Health Store Access for Lock Screen Widgets
 
 
Q