Hello,
I have a question regarding the behavior of BGProcessingTaskRequest when the app is force-quit by the user via the App Switcher.
Based on common understanding and various discussions — including the following Apple Developer Forum threads:
- Waking up an iOS app after app is … | Apple Developer Forums
- Will BGAppRefreshTaskRequest will … | Apple Developer Forums
- Background fetch after app is forc… | Apple Developer Forums
…it is widely understood that iOS prevents background execution (such as background fetch, push notifications, or BGTaskScheduler) after a user force-quits an app via the App Switcher.
However, in my app, I have observed that a scheduled BGProcessingTaskRequest still executes even after the app has been explicitly terminated via App Switcher. The task is scheduled using submit(_:error:), and it is clearly running some time after the app has been closed by the user.
That said, the task does run, but it appears to operate under tighter constraints — for example, it may be allowed to run for a shorter duration, and network requests appear to be more restricted compared to when the app is not force-quit.
My questions are:
- Are there any documented or undocumented exceptions that allow this kind of behavior after force-quit?
- Could this be a bug or a behavior change in recent iOS versions? (I am observing this on iOS 18.3, 18.4, and 18.5)
Any insights, experiences, or clarifications from Apple engineers or fellow developers would be greatly appreciated.
Thank you!
However, in my app, I have observed that a scheduled BGProcessingTaskRequest still executes even after the app has been explicitly terminated via App Switcher.
...
Are there any documented or undocumented exceptions that allow this kind of behavior after force-quit?
Yes, the behavior here is an intentional choice by the engineering team to work around a very specific (and common) usage pattern. BGProcessingTaskRequests are designed to run when they're least likely to disrupt the user, which, in practice, means they tend to run "in the middle of the night" (say, ~3 a.m.) when the user is charging their phone. However, the problem here is what happens with apps that have a usage pattern like this:
-
Every morning, the user gets up and runs the app (for example, they're checking the morning traffic).
-
Later in the day, they force quit the app and they want it "out of the way".
-
They never launch the app again because "they only run it in the morning".
-
They go to bed, and the cycle starts all over again in the morning.
Note that this is just one example among many. As another example, it's pretty common for users to end turn-by-turn direction sessions by force quitting the app, simply because it's faster than opening the app and pushing "stop".
In any case, there are many cases where an app clearly "should" be able to use BGProcessingTaskRequest because it's a heavily used app, which the normal force quit behavior would prevent.
With that background, returning to the question...
Are there any documented or undocumented exceptions that allow this kind of behavior after force-quit?
What the BackgroundTask framework does is run the processing task once, even if the app has been force quit, and then ignore that app’s task until the app is run again (which “resets" the behavior). This allows frequently used apps that the users happen to force quit to use BGProcessingTaskRequest, while still preventing BGProcessingTaskRequest from being abused.
*As I noted above, many force quits are as much about interface "convenience" and not any issue/concern about the app being terminated.
Could this be a bug or a behavior change in recent iOS versions? (I am observing this on iOS 18.3, 18.4, and 18.5)
It's definitely not a bug nor is it new. It's always done this.
Some notes on this:
That said, the task does run, but it appears to operate under tighter constraints — for example, it may be allowed to run for a shorter duration, and network requests appear to be more restricted compared to when the app is not force-quit.
-
I don't think there is any specific logic that specifically restricts force-quit apps.
-
The "launch only one" behavior might make it look like there is. For example, if your task fails to complete it won't be allowed to run again until your app has been run again, which could mean that it ends up getting deferred longer than it "normally" would.
-
The system that prioritizes which task to run is complicated enough that it's difficult to predict EXACTLY how things will behave under any specific scenario. Basically, unless you're looking at a very large data set and well-controlled conditions, it's very assumed that differences are caused by some specific "choice" when they're actually caused by normal variation that you can't really see.
Particularly on that last point:
network requests appear to be more restricted
This isn't happening, at least not because of the background tasks framework. They're entirely different API stacks that don't really interact with each other.
*One possible explanation here is that NSURLSession has its own rule around how it handles background transfers, which is that it doesn't do background transfers for apps that have been force quit. I'm not sure how that would interact with BGProcessingTaskRequest, but it's certainly possible that you'd see different transfer behavior with NSURLSession.
Based on common understanding and various discussions — including the following Apple Developer Forum threads: ... …it is widely understood that iOS prevents background execution (such as background fetch, push notifications, or BGTaskScheduler) after a user force-quits an app via the App Switcher.
Again, just to make this clear, the behavior here is specific to BGProcessingTaskRequest, due to its unique role and how that interacts with common user usage patterns. Notably, BGAppRefreshTaskRequest does not relaunch for quit app and never has.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware