Code to run when app terminates from Suspended state - ios

I am working on an iOS app that has Multitasking enabled.Now, I want to perform some stuff when the app quits but not when it goes to the background. I understand we have following methods:
applicationWillEnterBackground:
applicationWillEnterBackground:
These methods are always called when app goes in background not necessarily getting terminated. I don't want to run my code if its in background but not terminating.
applicationWillTerminate:
This method works great if I terminate my app while in foreground or background but (according to Apple documentation) this method only gets called only when the app terminates while it is in foreground or background but not in the suspended state.
So, I would like to know how can I make my code run when the app is terminated while in suspended mode as well?
Any help would be appreciated.

Related

Detect when app killed by user in background state iOS

I am working in a chat application where I need to show user status (offline/online).
When my app is in foreground and background then I need to show user as online (managing by VoIP).
But when the user kill the app then it should go to offline.
I have to maintain a flag to show offline which I am managing in delegate function applicationWillTerminate but this function only called when app is in foreground state and user kill it by pressing double tap home button and swipe up.
This function does not get called when app is in background state. I mean simply press home by single tap (app will go in background) then again double tap to swipe up.
Is there any function where I get 100% call either app is in background/foreground state and user kill the app?
Is there any function where I get 100% call either app is in background/foreground state and user kill the app?
No. Just the opposite. If your app is terminated when already in the background, if it is suspended (ie not running in the background due to special entitlement), it is 100% certain you will get no event. You cannot. You are suspended and not running. The app dies in its sleep.
No, As per Apple Document
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623111-applicationwillterminate?language=objc
For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case.
What you can do execute a method(which hit an API for keeping status online) after few seconds(whatever you find suitable time) when you app goes in Background, If method is calling successfully after that specific seconds then user stay online, if its not call after specified second then server update its status to offline. So It require both server and client handling.

Is there anyway to check when an app will be suspended?

Is there a universal time of iOS app suspension time (i.e when it goes out of background mode and terminates).
Background
The app is in the background and executing code. Most apps enter this
state briefly on their way to being suspended. However, an app that
requests extra execution time may remain in this state for a period of
time. In addition, an app being launched directly into the background
enters this state instead of the inactive state. For information about
how to execute code while in the background, see Background Execution.
Suspended
The app is in the background but is not executing code. The system
moves apps to this state automatically and does not notify them before
doing so. While suspended, an app remains in memory but does not
execute any code. When a low-memory condition occurs, the system may
purge suspended apps without notice to make more space for the
foreground app.
No, there is not any possibility to know about that, according to this:
Suspended: ...The system moves apps to this state automatically and does not notify them before doing so...
Link: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html

handleActionWithIdentifier when app isn't launched

I've been using interactive notification and it works well when my app is suspended in the background, but causes problems when my app has been terminated.
I've used NSLog to determine the app's lifecycle when the interactive notification is triggered when the app has not launched.
The following goes on, in the order listed, without the app visibly launching:
didfinishlaunching
handleActionWithIdentifier
viewdidload
viewwilllayoutsubviews
viewdidlayoutsubviews
viewdidappear
The app then seems to terminate without calling
didenterbackground or willTerminate
The reason why it's causing issues for me is because I create timers in viewdidload that are invalidated in didenterbackground.
Because didenterbackground isn't being called, when the app is subsequently launched after triggering an interactive notification I'm ending up with two instances of the timer.
Could anyone shed some light on why the app terminates but didenterbackground or willTerminate aren't being called?
You should not assume that a call to didfinishlaunching means that you are in the foreground. As #PaulW11 says in his comment, for local notifications when your app is not running, you get launched directly into the background, and never see a foreground-to-background transition, because you were never in the foreground in the first place.
The system will call applicationDidBecomeActive: if you are being launched into the foreground. You should put your code that starts your timers there.
The docs say that local notification notices get invoked in the background:
When the user taps a custom action in the alert for a remote or local
notification’s, the system calls the
application:handleActionWithIdentifier:forRemoteNotification:completionHandler:
or
application:handleActionWithIdentifier:forLocalNotification:completionHandler:
method in the background so that your app can perform the associated
action.
You should write your application:handleActionWithIdentifier:forLocalNotification:completionHandler: method to check to see if it's being called from the foreground or from the background.
I use (Objective-C) code like this to tell if I'm in the foreground or the background:
BOOL inBackground = [UIApplication sharedApplication].applicationState == UIApplicationStateBackground;

iOS: force-closed app restarting in background

We're seeing a strange situation on our iOS app that is impacting our user experience.
When a user background's the app (by pressing the Home button), we can clearly see the app entering the background. When the user then force-closes the app (by double-tappinging the Home button and sliding-up on the app), the app terminates normally. When the app is then re-opened, it follows the normal iOS start-up sequencing.
However, if the user double-taps the Home button while the app is running (resigning the app from active, but not sending it to background) and then force-closes the app (by sliding-up on the app), we're seeing the app terminate (the process gets killed), but then the app immediately re-starts in the background (with a new pid). The app is not designed to start-up or run in the background, and this is causing UX issues.
The app has no entitlements to run in the background, although we do have a couple of third-party libraries that have tasks that wind-down when the app enters the background.
I suspect the issue is a result of the app being force-closed from a non-active state rather than a background-state. If the app enters the background first, the third-party tasks are getting a chance to complete. If the app is force-closed from the non-active state, the tasks never get a change to complete in the background, so iOS is restarting the app in background to give those tasks a change to finish. It's unclear, however, if this is correct behavior.
-Stix
I'm kinda thinking the questions were self-evident, but if not:
Is this correct behavior for iOS? Should iOS be restarting the app in the background when the user force-closes the app w/o putting it into background?
If this is correct behavior, what can cause this to occur? Is it possible some third-party framework - still running a background task that hasn't completed - is the culprit?
The force-close works fine if the app is put into background first (giving background tasks the ability to complete/expire). Is there anyway to force it into background when force-closing the app while it's in a non-active state?

Will background fetch be called when app is in background?

Will iOS call performFetchWithCompletionHandler for the running app that is taken to background (using Home button)?
I thought it is only called when iOS launches my app to do background fetch.
If iOS launches performFetchWithCompletionHandler even if my app is running in background, then I have one more question:
I need to fetch data from remote server periodically. I now use NSTimer and it works even when app is in background. My idea was to use background fetch to do it even if app is not running, but if enable background fetch, I may face situation when my own thread (with NSTimer) does some fetching and iOS calls performFetchWithCompletionHandler.
So, should I stop any timers when my app goes to background and wait for background fetch, then?

Resources