I'm trying to determine why my UIKit application was launched, specifically whether it was launched by the user or by the system to execute a background task.
I recently added a BGProcessingTask to update data overnight. Consider this scenario:
- The user backgrounds the app at 10 AM.
- A background task is scheduled with
earliestBeginDateset to 4 AM the following day. - During those 18 hours, iOS terminates the app's process to reclaim memory.
- iOS later decides to execute the scheduled background task and launches a new app process in the background.
My understanding is that this results in a cold launch, including a call to application(_:didFinishLaunchingWithOptions:) and the initialization performed there.
This matters because some of our startup initialization triggers network requests that are unnecessary when the app is launched only to perform a background task.
Questions
1. Can iOS relaunch a previously terminated app to execute a scheduled BGProcessingTask?
I'm referring specifically to termination by the system (for example, memory pressure), not the user force-quitting the application.
2. Is there a reliable way to distinguish a foreground cold launch from a background task cold launch inside application(_:didFinishLaunchingWithOptions:)?
I tried checking UIApplication.shared.applicationState, but in my testing it was .background during didFinishLaunchingWithOptions in both scenarios, including when the user launched the app by tapping its icon.
Is there another documented API or launch context that reliably identifies why the process was started? I'm aware that iOS provides launch options for certain launch scenarios, but I'm specifically interested in distinguishing a background task-triggered cold launch from a user-initiated foreground cold launch.
3. If this distinction cannot be made reliably during didFinishLaunchingWithOptions, what is the earliest lifecycle callback where I can determine that the app is entering the foreground?
For example, should foreground-specific initialization be deferred until scene(_:willConnectTo:options:), sceneWillEnterForeground(_:), or another callback?
I'm specifically looking for a documented and reliable lifecycle signal, rather than heuristics or arbitrary delays.
The goal is to avoid unnecessary startup initialization and network requests when iOS launches the application solely to execute a background task.