User terminates app forcefully: Registering this event - ios

In my app I use background services so the method applicationWillTerminate: will not get called when the user terminated the app. Instead the method applicationDidEnterBackground: gets called when the user pushed the app into to background and when the user terminates the app completely.
The problem I am having is that I need to be able to distinguish between when the user has pushed the app into the background and when he actually quits the app because I have different code that needs to be fired for both events.
Is this possible in my case?

The -applicationWillTerminate: method is called when the system is "nicely" terminating the application in an orderly fashion (ie, it's not being backgrounded for pending tasks or it told the OS those tasks are completed). This is distinctly different from "the user forcibly terminated the app", in which case your app won't receive any messages because it's just been summarily executed by a bullet to the head.
Are you certain you're correctly / fully participating in the background services? That is, are you certain you're correctly telling the system you've finished? You should edit your question and post the relevant backgrounding code. For example, if you're using -beginBackgroundTaskWithExpirationHandler:, the docs say:
If you do not call endBackgroundTask: for each task before time expires, the system kills the app.
...could this be your issue?

This is maybe not possible, but the only way I can imagine to distinguish between both of them is waiting to the next event.
When the next event is a "start", you know that the last event was a kill.
When the next event is a "foreground", you know that the last event was a background.
This implies some processing at server, I know.
Hope this helps.

Related

UNNotificationAction Handler on Low Power Mode

I am using Local Notifications with UNNotificationAction, when the user triggers the action I need to send an API request to the server.
When the device is on Low power mode and Background App Refresh is turned off and the app is killed, I get a weird behaviour on the action handler.
After the user taps the selected action on the notification - App Delegate didFinishLaunchingWithOptions() start to process but never finish.
It seems like the process is suspended in the middle of this function.
This behaviour also stops the handler function of the Notification Action.
After monitoring with logs (debugging from Xcode it always works), I see the state of the application is background on startup.
Also, I could not see any logs that indicate crush or process suspension
I could not find any documentation of handling such a case.
This is quite a long shot, and I don't know if it will solve your issue, but remember that there are limitations regarding what can you do inside the didFinishLaunchingWithOptions method. IIRC, if that method takes more than 10 seconds to execute, the application gets killed (the system thinks something went reeeally ballistic). So, if you need to trigger something heavy through that method, make sure you run it asynchronously.

Fetch location when user forcefully quit the application in iOS

I want to fetch location in background even if user forcefully quit the app. Currently my applicationDidEnterBackground method not called when user quit the app. It only works when user simply click on the home button.
Please refer to applicationWillTerminate
By Apple documentation it says:
This method lets your app know that it is about to be terminated and purged from memory entirely. You should use this method to perform any final clean-up tasks for your app, such as freeing shared resources, saving user data, and invalidating timers. Your implementation of this method has approximately five seconds to perform any tasks and return. If the method does not return before time expires, the system may kill the process altogether.
For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app. 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. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason.
After calling this method, the app also posts a
UIApplicationWillTerminate
notification to give interested objects a chance to respond to the transition.
If you want to have user's location when app is not in memory, short answer: Impossible.

What iOS app delegate methods does the springboard kill trigger? [duplicate]

What is the delegate method for detecting when application was closed.
I mean when user tap this button:
I know about method below:
- (void)applicationDidEnterBackground:(UIApplication *)application;
- (void)applicationWillEnterForeground:(UIApplication *)application;
But they work not as I expected in my case. For example I have used my app and I have navigated to some screen. In case when I lock screen and go back to app the app calls applicationWillEnterForeground but I don't need this, because I am still on this view (for example Test Screen View)and I don't need to check any changes. But in case if my app closed I begin to navigate from start app for example Home Screen. So if my app was closed and I am on Home Screen I need to check if in previous time I had some actions (for example if I passed test on Test Screen View) and present this view controller (ONLY IN CASE IF I CLOSED APP NOT JUST LOCKED IT OR ENTER BACKGROUND).
Thanks for help.
You can't detect this. From the iOS App Programming Guide ("App Termination" heading):
Important: The applicationWillTerminate: method is not called if your app is currently suspended.
Even if you develop your app using iOS SDK 4 and later, you must still
be prepared for your app to be killed without any notification. The
user can kill apps explicitly using the multitasking UI. In addition,
if memory becomes constrained, the system might remove apps from
memory to make more room. Suspended apps are not notified of
termination but if your app is currently running in the background
state (and not suspended), the system calls the
applicationWillTerminate: method of your app delegate. Your app cannot
request additional background execution time from this method.
You can't. When your app is killed in this manner, it is not told anything. The app is killed by the OS with no warning of any kind.
When your app enters the background, you have no way to know if will be started fresh or simply return to the foreground. Therefore you must properly handle things when the app enters the background.
When the app starts again, restore whatever state you need.
On iOS, you cannot check for that. That is: the process is SIGKILL'ed. One way I know that might be able to work relies on the fact that to kill an app, one has to suspend it first by pressing the home button.
Hence, you can gather your actions as the user uses the app, commit it to a saved place when the user suspends the app. If the user resumes, reset the list and start gathering info again. However, if the user suspends the app and you never get a resume, on the next app start, you can read the list and recover from there.
HTH
You can implement the -applicationWillTerminate: method of your UIApplicationDelegate delegate to respond to termination events. However, it's not guaranteed to be called in all cases, so you should not rely on it being called. According to the iOS App Programming Guide:
If your app is running (either in the foreground or background) at termination time, the system calls your app delegate’s applicationWillTerminate: method so that you can perform any required cleanup. You can use this method to save user data or app state information that you would use to restore your app to its current state on a subsequent launch. Your method has approximately 5 seconds to perform any tasks and return. If it does not return in time, the app is killed and removed from memory.
Important: The applicationWillTerminate: method is not called if your app is currently suspended.

iOS how to detect when app was removed from process

What is the delegate method for detecting when application was closed.
I mean when user tap this button:
I know about method below:
- (void)applicationDidEnterBackground:(UIApplication *)application;
- (void)applicationWillEnterForeground:(UIApplication *)application;
But they work not as I expected in my case. For example I have used my app and I have navigated to some screen. In case when I lock screen and go back to app the app calls applicationWillEnterForeground but I don't need this, because I am still on this view (for example Test Screen View)and I don't need to check any changes. But in case if my app closed I begin to navigate from start app for example Home Screen. So if my app was closed and I am on Home Screen I need to check if in previous time I had some actions (for example if I passed test on Test Screen View) and present this view controller (ONLY IN CASE IF I CLOSED APP NOT JUST LOCKED IT OR ENTER BACKGROUND).
Thanks for help.
You can't detect this. From the iOS App Programming Guide ("App Termination" heading):
Important: The applicationWillTerminate: method is not called if your app is currently suspended.
Even if you develop your app using iOS SDK 4 and later, you must still
be prepared for your app to be killed without any notification. The
user can kill apps explicitly using the multitasking UI. In addition,
if memory becomes constrained, the system might remove apps from
memory to make more room. Suspended apps are not notified of
termination but if your app is currently running in the background
state (and not suspended), the system calls the
applicationWillTerminate: method of your app delegate. Your app cannot
request additional background execution time from this method.
You can't. When your app is killed in this manner, it is not told anything. The app is killed by the OS with no warning of any kind.
When your app enters the background, you have no way to know if will be started fresh or simply return to the foreground. Therefore you must properly handle things when the app enters the background.
When the app starts again, restore whatever state you need.
On iOS, you cannot check for that. That is: the process is SIGKILL'ed. One way I know that might be able to work relies on the fact that to kill an app, one has to suspend it first by pressing the home button.
Hence, you can gather your actions as the user uses the app, commit it to a saved place when the user suspends the app. If the user resumes, reset the list and start gathering info again. However, if the user suspends the app and you never get a resume, on the next app start, you can read the list and recover from there.
HTH
You can implement the -applicationWillTerminate: method of your UIApplicationDelegate delegate to respond to termination events. However, it's not guaranteed to be called in all cases, so you should not rely on it being called. According to the iOS App Programming Guide:
If your app is running (either in the foreground or background) at termination time, the system calls your app delegate’s applicationWillTerminate: method so that you can perform any required cleanup. You can use this method to save user data or app state information that you would use to restore your app to its current state on a subsequent launch. Your method has approximately 5 seconds to perform any tasks and return. If it does not return in time, the app is killed and removed from memory.
Important: The applicationWillTerminate: method is not called if your app is currently suspended.

How to resume (or launch) my app after a phone call ends in iOS (my app did *not* initiate the phone call)?

I have seen several ways to "make sure that my app is shown again after a phone call which my app has initiated has ended" however that isn't what I want -> what I am looking for is a way to, say my app is currently running in the background doing network communications and someone calls me, I would like my app to either be able to "detect when the phone call has ended and resume my network communications" and/or "launch/resume my app back into the foreground when the phone call has ended". Is there any way to accomplish something like this and how?
This is unsupported within iOS.
From the docs:
http://developer.apple.com/iphone/library/documentation/iphone/conceptual/iphoneosprogrammingguide/BackgroundExecution/BackgroundExecution.html
http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Reference/CTCallCenter/Reference/Reference.html#//apple_ref/doc/uid/TP40009604
If your application is active when a call event takes place, the system dispatches the event to your handler immediately. However, call events can also take place while your application is suspended. While it is suspended, your application does not receive call events. When your application resumes the active state, it receives a single call event for each call that changed state—no matter how many state changes the call experienced while your application was suspended. The single call event sent to your handler, upon your application returning to the active state, describes the call’s state at that time.
The best you can do is detect phone calls while your app is open.
applicationWillResignActive is called when the app is about move from active to inactive state. So if you get a call, this method is called before your app is backgrounded.
Use this method to pause any ongoing tasks and save any settings you need.
applicationDidBecomeActive is called when you app becomes active again.
Use this method to resume any tasks that were suspended. Example would be resuming your network communications

Resources