BGProcessingTask expirationHandler — No way to distinguish expiration reason

The expirationHandler on BGProcessingTask is a () -> Void closure. It provides no information about why it was called.

In my testing, all of the following trigger the same handler:

  1. Time expiration
  2. Resource pressure (CPU, memory, battery)
  3. Not reporting progress
  4. User tapping "Stop" on the Live Activity

There is no way for the app to tell these apart.

Questions:

Q1. Is there an official, complete list of all conditions that trigger expirationHandler? The documentation only mentions "time expires."

Q2. What is the specific time limit before timeout? If it varies by device state, what are the conditions?

Q3. A way to distinguish the reason is needed. "User stop" and "system expiration" require completely different handling. Currently this is impossible.

Environment: iOS 26, physical device

Is there an official, complete list of all conditions that trigger expirationHandler?

No. It’s unlikely that we would ever publish such a list because it’s an implementation detail, one that we want to be able to change as the system evolves.

What is the specific time limit before timeout?

Again, this is something we specifically don’t document.

A way to distinguish the reason is needed. "User stop" and "system expiration" require completely different handling.

I was investigating this when I realised that I’m confused about the context here. You mention BGProcessingTask but those tasks don’t have a UI presence. Are you actually using BGContinuedProcessingTask?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

BGProcessingTask expirationHandler — No way to distinguish expiration reason
 
 
Q