I, I want notify to my server when my iOS objective c application is closed by a user, and I want add a call into my applicationWillTerminate delegate function.
But I don't know if it is possible, because I have added a UILocalNotification and it isn't showed...
Could I call my server when the user close the app?
This method is rarely called and not reliable but why not to save some settings on these methods
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
so that when you open the app again you check these values and call the service you wanted
Related
Sometimes user presses the home button and close the application from recent list.
I want to warn user with a message like "This application not properly closed last time".
How to detect such unexpected closing of application? Is there any way to do it?
Also i would like to save the data filled by user.
The below method works good but after staying in background for a while and closing the application will not get invoked to this method.
- (void)applicationWillTerminate:(UIApplication *)application
Is there any solution in swift 3.0 ?
To save the data filled by the user, you should use the func applicationDidEnterBackground(_ application: UIApplication) function.
This is the function description:
// Use this method to release shared resources, save user data,
invalidate timers, and store enough application state information to
restore your application to its current state in case it is terminated
later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user
quits.
As for "This application not properly closed last time" message you want to present the user - it's wrong to show such a message.
The way to close the app is to press the home screen and close it from the list, so this is the expected behavior.
Please check this to understand how iOS application lifecycle works - https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html
Now in your project find this following methods to track your app's lifecycle process.
For Objective-C
- (void)applicationWillResignActive:(UIApplication *)application{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillTerminate:(UIApplication *)application{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
}
For Swift(3.0)
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
}
Hope this helped.
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.
-(void) applicationWillTerminate:(UIApplication *)application{ }
You can use AppDelegate Method resignActive for saving data when user send app to background. And save a boolean value true in NSUserDefaults if it launches from didFinishLaunching method and check this boolean and saved data for computation in method didBecomeActive. Using data and boolean value you can show alert and reset both values.
If the user kills the app manually while the app is not suspended, the applicationWillTerminate will be called in your app delegate.
When the user just press the home button the applicationDidEnterBackground is called in your app delegate.
If the applicationDidEnterBackground is called, and the applicationWillTerminate is not probably the app was not killed properly.
I said probably because there is no warranty that the applicationWillTerminate is called in case of app kill. In fact if the app is suspended the method will not be called.
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.
source: https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate
The scenario when a manual kill would not cause this method to be called is when the user push the home button, and after a while he double press the home button and kill the app. In this scenario iOS would call applicationDidEnterBackground in your delegate when the user press the home button, and after ~5 seconds the app would get the status of suspended. When the user kills the app later on, its status would be suspended, and the willTerminate method would not be called.
the same happens if while suspended iOS kills the app to get resources giving to it the status of terminated.
What I would do is to persist the timeStamp of the applicationDidEnterBackground method call, cancel it on applicationWillEnterForeground and in the applicationWillTerminate.
If the next time that your application(_:willFinishLaunchingWithOptions:) gets called you have a value for the timestamp saved in the applicationDidEnterBackground it means that the user did not manually kill the app (maybe) and he did not come back after putting it in background.
If the user killed the app while the app was suspended, maybe in your case it would still be considered a misuse of the app, and the message can be displayed, so that all the use case are covered.
You shouldn't do that but if we are speaking about theory then the solution is to show the alert always except the first run.
I would save a boolean in UserDefaults, let's call it shouldShowWarning.
Everything else can go inside:
UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)
Inside the method you can check whether shouldShowWarning is true. If it's true, show the warning.
Then set the value to true.
Now if the app is terminated and you return back, the alert will be shown.
If there is some scenario when you are terminating the app from code (which is very non-standard), just set shouldShowWarning to false to disable the warning when the app is restarted.
You can do this by listening to UIApplicationWillResignActiveNotification notification.
Detect when home button is pressed iOS
In the Application Delegate, you can check for different events. Check for applicationWillResignActive method or ApplicationDidEnterBackground.
The appropriate location will depend on your usecase.
My App goes in background, If I open again, It shows same page where I left it.
While, If iOS puts app into Suspended state, yet it is in memory. If I come back, which AppDelegate methods will be called.
Actually my purpose is to restore same screen from suspended to app, if it is not TERMINATED.
Last thing, Will didFinishLaunchWithOptions will be called if App is returning from SUSPENDED state.?
Thanks..
As Apple Documentation states,
application:willFinishLaunchingWithOptions:—This method is your app’s first chance to execute code at launch time.
application:didFinishLaunchingWithOptions:—This method allows you to perform any final initialization before your app is displayed to
the user.
applicationDidBecomeActive:—Lets your app know that it is about to become the foreground app. Use this method for any last minute
preparation.
applicationWillResignActive:—Lets you know that your app is transitioning away from being the foreground app. Use this method to
put your app into a quiescent state.
applicationDidEnterBackground:—Lets you know that your app is now running in the background and may be suspended at any time.
applicationWillEnterForeground:—Lets you know that your app is moving out of the background and back into the foreground, but that
it is not yet active.
applicationWillTerminate:—Lets you know that your app is being terminated. This method is not called if your app is suspended.
so applicationWillEnterForeground and applicationWillResignActive will be get called!
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
didFinishLaunchWithOptions didnt call.
Accoding to application's life cycle, Your app will not get any notification when ios will put your app in suspended mode. Whenever your app enters in background mode and if its not doing anything - not processing - ios will put it in suspended state.
But when suspended and its still in memory, You don't really need to do anything to display same screen where your app was before. ios automatically keep the state of app. You need to manage this only if your app is getting terminate while in suspended mode ..i.e. not in memory.
If you don't have any execution in background with any of background execution method , you can consider app in suspended mode if you receive notification for applicationDidEnterBackground store state of your app somewhere and applicationWillEnterForeground you can display app with stored state.
or if you are executing some finite task in background, You can keep local variable and use that for keeping track of suspended or now. on applicationDidEnterBackground, variable = inBackground, when you task completed and variable == inBackground, set variable == inSuspended and also store state of your app somewhere. on applicationWillEnterForeground
if variable == inSuspended
{
//Display app according to previously stored state.
`variable == inForgorund`,
}
You can test it your self using breakpoints in AppDelegate file.
If user will click on Home button once, app is in suspended state.
If user will click on Home button twice, app is in inactive state.
While user comes from suspended state to the app, I found following method calls.
first : applicationWillEnterForeground then applicationDidBecomeActive.
didFinishLaunchingWithOptions not called.
More details
- (void)applicationDidEnterBackground:(UIApplication *)application {
//...function_a call
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
//...function_b call
}
- (void)applicationWillTerminate:(UIApplication *)application {
//...function_c call
}
I'm tracking my app with AppDelegates methods. Its working fine, if app just go / up from background to foreground. But when I try to remove my app from the running applications then, it will first call - (void)applicationDidEnterBackground:(UIApplication *)application and then, will call - (void)applicationWillTerminate:(UIApplication *)application. How do I know in - (void)applicationDidEnterBackground:(UIApplication *)application that app is being terminating. By mean, I don't want function_a call twice instead it should only call when app goes into background.
Update:
Setting even following observer doesn't help.
UIApplicationDidEnterBackgroundNotification
UIApplicationWillEnterForegroundNotification
UIApplicationWillTerminateNotification
- (void)applicationWillTerminate:(UIApplication *)application:
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.
So this is the to go delegate method to know when the app will be terminated, either by the user or by the system, while - (void)applicationWillTerminate:(UIApplication *)application runs whenever the app goes to the background, it doesn't mean it was exitted, unless your exit means not visible
I am developing an app that's reading a db from parse.com with coordinates plotting out on a MapKit-map. Everything works fine but when a new pin is added manually by me on the web at parse.com, it doesn't show up when opening the app after pushing the home-button on my phone.
Where and how could I ask if the app has been shot down?
Hope I explained in an understandable way.
It could also be nice to have the app opening from scratch every time it is opened with the launch-image and so on. But I suppose that is not possible as one always has to close apps that are in the background by double-clicking on the phone.
Thankful for answers
If by 'app has been shot down' you mean the app moved to background after pressing the home button, then to know about this event you need to implement applicationDidEnterBackground: method in your appdelegate.m
These functions along with comments are created by xcode, when you start a new project.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"App Background");
/* Use this method to release shared resources, save user data,
invalidate timers, and store enough application state information
to restore your application to its current state
in case it is terminated later.
If your application supports background execution,
this method is called instead of applicationWillTerminate:
when the user quits.
*/
}
To know when the app was opened again, implement applicationDidBecomeActive: method in your appdelegate.m
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(#"App Active");
/* Restart any tasks that were paused (or not yet started)
while the application was inactive.
If the application was previously in the background,
optionally refresh the user interface.
*/
}
I would like to record a timestamp whenever the user opens the app. Now, I was able to record in the ViewDidLoad method, however, once the user closes the app and it goes to the background and then open the app once more, I can't get the timestamp, because ViewDidLoad doesn't run anymore. Does any of you have any idea where to put my timestamp code?
You could put it inside - (void)applicationDidBecomeActive:(UIApplication *)application , but it isn't a good approach, since the user starting the app isn't the only activity that will cause the timestamp to be saved, as there are other situations when this method might get called.
From Apple's Documentation
applicationDidBecomeActive: Tells the delegate that the application
has become active.
This method is called to let your application know that it
moved from the inactive to active state. This can occur because your
application was launched by the user or the system. Applications can
also return to the active state if the user chooses to ignore an
interruption (such as an incoming phone call or SMS message) that sent
the application temporarily to the inactive state.
The correct approach is to put the code that stores the timestamp both inside application:didFinishLaunchingWithOptions: and applicationWillEnterForeground:
The first method will get called on the first launch and the second one when the application is launched from the background. Since an ignored interruption wouldn't send the app to the background, applicationWillEnterForeground would not get called in this case, so you wouldn't have a timestamp stored after the user ignores a phone call for example.
Check this answer, since it very well summarizes the role of the methods involved in handling sending an app to the background and getting it back to the foreground and what should you use each of them for.
Implement applicationDidBecomeActive: in your app delegate or observe the UIApplicationDidBecomeActiveNotification notification.
Try using - (void)viewDidAppear:(BOOL)animated:
instead. It is called whenever the view appears on the screen.
Or you can look into the UIApplicationDelegate and try implementing something like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
or
- (void)applicationDidBecomeActive:(UIApplication *)application