This question already has answers here:
What is the Life Cycle of an iPhone application? [closed]
(4 answers)
Closed 9 years ago.
I am trying to create an iOS crash reporter tool. I wonder if the application can send crash info after it was terminated.
So my questions are:
- What is a lifecycle of iOS application after termination?
- Where can I read more about what iOS does to application on termination?
Doing any non async-safe task when the app crashed is highly NOT-recommendable!
You are not allowed to allocate any new memory at that time
You are only allowed to use async safe code (Any Objective-C code is NOT async safe)
You need to take into account that memory is already corrupted
You need to implement async-safe networking code
and many many more reasons.
See these blog posts from Landon Fuller, the author of PLCrashReporter:
http://landonf.bikemonkey.org/code/crashreporting/Reliable_Crash_Reporting_1.1.20130119.html
http://landonf.bikemonkey.org/code/objc/Reliable_Crash_Reporting.20110912.html
You are trying to solve a problem, that is not a problem in the real world. People do restart their apps and will send the crash reports.
Yep, a sort of... you can handle exceptions, before iOS kills the crashing app, but you can't do any async operation (probably not totally true you can use background operation with expiration handler, or in iOS7 NSURLSession), such as sending the a file to a server, but you can do at the next restart.
The idea behind that is in -applicationDidFinishLaunching to set an exception handler:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&myExcHandler);
/* your code*/
}
myExcHandler is a C callback that accept an NSException as parameters that it will be called when an exception occurs.
void myExcHandler(NSException *exception)
{
//set something on NSUserDefault to check at next start
}
It must be said that there are plenty of crashing report lib available. Do not reinvent the wheel ;-)
The last event you got for application terminate is in applicationWillTerminate method . This method will not called if application is suspended . You can monitor crash log on your machine of application if your application crashed after termination here :
~/Library/Logs/CrashReporter/MobileDevice/<your iPhone’s name>/
From Apple docs
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.
Scroll down to "App Termination" to read more information about this.
Hope it is of any help
Related
How can I check if user has exited the app, so I can make sure the app will shutdown?
I am currently using Swift - Xcode 6.3.1
In the AppDelegate class (AppDelegate.m) there is a function called applicationWillTerminate:(NSNotification*)notif. This function will be called when the application has been quit. This is where you put any code that you have to call before quitting the app (e.g. closing files, deleting timers, etc). This is automatically called when the app closes, you don't have to check yourself.
In iOS you don't (in general) terminate an app. You should design your app such that if the user moves away from it (e.g. presses the Home button) that it is ready for when they decide to come back. You also need to design it such that if iOS terminates it (e.g. due to memory limitations) that no user data is lost and that all is right next time the app launches (the general guidance here is that the user cannot tell that the app terminated - but a lot of apps don't succeed in that). But otherwise you do not need to do anything when the user 'goes away' from your app.
See this Apple document for the official line on not terminating. See this Apple document for more details on the App lifecycle in iOS.
The sole exception is that you may want to terminate if a fatal error occurs - in Swift you can use fatalError to do this, but it will look like a crash to your user.
While the device is powered on, is it possible for iOS to automatically terminate my app (calling applicationWillTerminate:) while it's in the background?
I'm also curious what happens in two other cases, three in total:
Device is powered on
Device is powered off
Device loses battery
I'm asking because I want to know how often applicationWillTerminate: is likely to get called. I want to know this because that's where I'm registering for remote notifications. And if there's a failure sending the device token to the server, I want to know how likely it is that that method will get called again (i.e., retry sending the device token to the server).
If your application supports multitasking (the default for anything linked against iOS 4.0+), this method will almost never be called. The documentation says it may be called in cases where the application is running in the background and the system wants to terminate. However, in my experience, I've only ever seen this actually called when running a music app that's actively playing music in the background and the system is jettisoning everything. In cases where I have background tasks running (not music, but short-term background tasks), I've seen the app terminated without this method being called.
I wouldn't ever rely on this being called and try and do all the clean-up you need to do in your delegate methods for transitioning into the background and your background task completion blocks (which do get executed for at least a few seconds before the app gets jettisoned).
Not only can iOS terminate your app automatically, but the user can kill it manually. In fact, the only time the user can kill your app is when it's in the background. Furthermore, when your app is "in the background" it's more likely to be suspended than actually running, so don't count on doing a lot of processing when you're not the foreground app.
As for how likely it is that you'll get -applicationWillTerminate:, that'll depend on the user and how they're using their device. You should handle it appropriately when you get it, and go about your business otherwise.
When memory is running low, iOS can shut down your app, calling applicationWillTerminate.
The docs say this about the method:
... However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.
Check out iOS Developer Library : iOS App Programming Guide : App Termination.
So here is the issue I am facing. Certain portions of the application I am building open some c network sockets that allow connections to various servers/services. However, if the application goes to sleep, these socket connections are lost, and error out when trying to reload them. So what I want to do is basically notify the user when the app launches again, that the application needs to be restarted. The main question is, can I present them with a button that will kill the app by using exit(0) without my app getting rejected?
Apple says that the user should be in control of when the app is killed, and in this case I see that they are, but I am not sure of Apple's opinion on this. Has anyone else used this? Have you been rejected for this? Thanks in advance for any advice!
EDIT:
Thank you everyone for your advice. I am trying to take everything into consideration, but because the app needs to be submitted ASAP, I just need to know, if we can not get another solution, if the above proposed solution, will get rejected or not.
Your application delegate receives notifications when significant events affect the life of the application. Rather than ask your user to recreate a session, you should attempt to discontinue network operations and then resume them at the appropriate times in the application's lifecycle automatically.
You can gracefully kill network sockets (amongst other things) in any number of places as the application prepares to exit or enter the background via callbacks in your application delegate:
applicationWillResignActive:
applicationWillEnterBackground:
applicationWillTerminate:
Potentially reconstruct sockets in:
applicationDidBecomeActive
applicationWillEnterForeground
Have you tried not allowing the app to run in the background? Then it will be killed whenever the user exits to the home screen. This might be a bit aggressive, but would solve the problem. From Apple's opting out of background execution:
"If you do not want your application to remain in the background when
it is quit, you can explicitly opt out of the background execution
model by adding the UIApplicationExitsOnSuspend key to your
application’s Info.plist file and setting its value to YES.
When an application opts out, it cycles between the not running,
inactive, and active states and never enters the background or
suspended states.
When the user taps the Home button to quit the application, the
applicationWillTerminate: method of the application delegate is called
and the application has approximately five seconds to clean up and
exit before it is terminated and moved back to the not running state."
See also: How to prevent my app from running in the background on the iPhone
The documentation is pretty explicit about this, "There is no API provided for gracefully terminating an iOS application." See Technical Q&A QA1561
How do I programmatically quit my iOS application?.
To be blunt, terminating an app to cleanup a socket is just like dealing with memory management by forcing an app to exit instead of calling release.
What about bringing up a modal view controller telling the user to quit the application? You could make this view controller without any dismiss button, so the user is obligated to kill the app.
I m facing big problem With Application Termination State.In My app
need to Satisfied Following Points.....
1)Application Is in Back Ground Switch To Fore Ground (no Need To
Store Data)
2)Application Is Background After Some Time If User Go to home And
Terminate Application (need To Store Data)
is there any delegate method Will Call Before Application
Terminate . - (void)applicationWillTerminate:(UIApplication
*)application
Is not Working With Because In 1 Case Application Running So
Suspended When We Try to Terminate Application.
Please Help me Out From This Issue..... If Any Ideas Also Would Be
Appropriated
You should always store your data when going into the background (applicationDidEnterBackground:). There is no guarantee that you will receive any further opportunities prior to being terminated.
This is how it's supposed to work. This is what it says in the documentation:
For applications that support background execution, this method is
generally not called when the user quits the application because the
application simply moves to the background in that case
If there is data that you need to save, you should do it when the app goes into the background.
No there is nothing called, because your app killed by the OS, this could also happen if the system need more free memory.
You should save the data when every your app gets send to the background, not when it gets terminated.
Hee
Does anybody know how to recognize a multitask-kill.
When the user puts the application in background state and then kills the app through the menu in iOS 4.2 my application shuts down.
Before there used to be an function called:
- (void)applicationWillTerminate:(UIApplication *)application
This method is not called anymore in iOS 4 and higher.
Is there a way to recognize it?
Thanks already.
Actually that's not entirely true. It is called on iOS4 devices that do not support multi-tasking and the documentation says that it can be called on other handsets (though I've never seen it myself).
But to answer your question, no, you can't recognise when a user kills your app. If you have state that you want to save you need to do this when your app goes into the background and not when the app is killed.
If you look at the crash reports you'll see that iOS sends SIGKIL which you can't catch.
You cannot catch this, your processed really is killed. Hard. Without notice. That us why you need to save state when you enter background now.
Maybe setting up a signal handler might work (don't know which signal to catch, though).