Thank you very much for your response!
Let me first describe the overall startup process of my application, how we determine abnormal exits, and how we identify background launches.
In application:didFinishLaunchingWithOptions:, we conduct the overall startup process of the application. We log every key path within this process, and we print the UIApplication.appState to determine the application’s foreground and background states at each key point. Additionally, we log many key paths during the user's interactions, which also include UIApplication.appState.
In various lifecycle APIs of AppDelegate, we also print logs to confirm the overall lifecycle of the application. Due to historical reasons, our application does not use SceneDelegate.
To determine abnormal exits, when application:didFinishLaunchingWithOptions: is called, we start listening for foreground and background notifications, UIApplicationWillTerminateNotification, and atexit. We only write a file named "normalExitFile" when receive UIApplicationDidEnterBackgroundNotification, UIApplicationWillTerminateNotification, or atexit.
When the application starts, we first check whether the "normalExitFile" exists and whether a crash occurred last time (we also write a file when we received crash signals). If both are absent, we conclude that the user had an abnormal exit last time. At this point, we report the user logs to the server, delete the "normalExitFile" to reset the application to its initial state, and then begin listening for the next lifecycle processes (foreground and background notifications, UIApplicationWillTerminateNotification, atexit).
Starting from May, the quantity of these abnormal log reports surged. We noticed that a small portion of the logs had appState aligning with our expectations, transitioning from UIApplicationStateInactive to UIApplicationStateActive, and the final logs were all UIApplicationStateActive, with no logs indicating a background transition (logs indicating transitions to the background also had corresponding logs for returning to the foreground). We consider these logs to be normal, indicating that the user experienced an abnormal exit.
However, for the majority of the other logs, the appState remained UIApplicationStateBackground throughout, with no UIApplicationStateInactive printed, or any other lifecycle log prints. This suggests that from the moment application:didFinishLaunchingWithOptions: was called, the UIApplication.appState has consistently been UIApplicationStateBackground.
From the logs, we can confirm that application:didFinishLaunchingWithOptions: was invoked. Particularly while determining whether it was a background launch, I added logs of user actions (whether user had clicked somewhere last time) and periodic logging (To check if the UIApplication.appState has change). For these background launch logs, it's clear that no user click events occurred at any point, and most periodic logs ceased around the 30-second mark. This led me to initially suspect silent notifications, as I read in the documentation that silent notifications provide the application with 30 seconds to process.
However, the logs printed in userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: did not appear in the background launch logs, so can I rule out silent notifications as the cause?
Do you become the "Now Playing" app? Now playing apps can also be launched into the background and (I think?) PiP support requires "Now Playing".
We do use the Now Playing feature, but that was introduced in January last year, which doesn't align with the timing this May. Of course, it could be that there is increased usage of Now Playing in some business flows. Is there a way to determine if Now Playing triggered the background launch?
Or with more information I provided, do you have any other suspects? Thanks for your time.