Is there a way to find if my app has crashed on previous launch. I want it from both swift and obj-c without using any 3rd party libraries? I want a way to note that my app has crashed, no stack trace needed just want some count of crashes stored to user defaults. I saw NSSetUncaughtExceptionHandler being used but it is only catching obj-c related errors. eg. force unwrapping nil is not caught here. I want a universal way of catching the crashes, also want to know if this can affect the crash reporting by 3rd party libraries. How do 3rd party libraries do this? Found a repo: Crash Eye but it is not really catching all the crashes. This might seem repetitive but most answers on SO are not complete.
Asked
Active
Viewed 78 times
0
-
If you don't want to add a third party library, and very likely also don't want to add your own crash handler (which is quite complex), the answer is No. The things you can actually do in a crash handler (not an exception handler!) is very, very limited and requires special knowledge to implement properly. – CouchDeveloper Aug 07 '23 at 12:59
-
So what is outlined in the posts above is an exception handler and not a crash handler and that is why we are unable to catch crashes like nil unwrapping? – Keer Aug 07 '23 at 13:05
-
2Objective-C exceptions are not crashes. In Swift there are no such "exceptions" at all. In Swift, Objective-C exceptions are a very legacy concept. Yet, neither Swift Errors nor Objective-C exceptions are "crashes". Crashes may be caught by signal handlers. The library you linked, "Crash Eye" gives a clue what this is and how you catch those events. – CouchDeveloper Aug 07 '23 at 13:10
-
Does this answer your question? [Swift: Natively Detect if App has Crashed](https://stackoverflow.com/questions/37220379/swift-natively-detect-if-app-has-crashed) – HangarRash Aug 07 '23 at 17:36
-
@HangarRash yes I saw this but as you have mentioned this is not called in all cases and I want some way of assuring that a crash has occurred. There is a chance that it may not get called giving me a false crash. I want a solid way of identifying that the crash has occurred. Also how do the 3rd party libraries do it? Very curious. – Keer Aug 07 '23 at 19:12
-
@CouchDeveloper the signal handler approach is not able to catch all crash occurrences. Any suggestions around this? I implemented it as given in the Crash Eye library. – Keer Aug 07 '23 at 19:19
-
What kind of crash do you mean specifically? Note, that "crashes" are caused by special CPU instructions generated by the source code (Int overflow, array index out of range,...) or caused CPU exceptions generated by the CPU itself (div by zero). We say it's a "crash" when the app terminates or aborts unexpectedly. However, the app also terminates, when the OS orderly terminates your app, or when the source code executes `fatalError()`. There are also CPU exceptions which are vital to the system, for example to implement virtual memory. – CouchDeveloper Aug 08 '23 at 08:46
-
If you are not successful with "Crash Eye", you may try [PLCrashReporter](https://github.com/microsoft/plcrashreporter). In my experience, the most reliable and battle tested library for mac and iOS. – CouchDeveloper Aug 08 '23 at 09:03
-
@CouchDeveloper Thanks but I don't think I can use a 3rd party library and implementing something on the level of PLCrashReporter may take time. Does the answer given below by Kasparian seem like a possible approach? – Keer Aug 08 '23 at 19:38
-
You can read about `applicationWillTerminate(_:)` in the [official documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623111-applicationwillterminate). This delegate method will only be called, when the app will be terminated in an _orderly fashion_ – not when it crashes. BUT, my definition what "crash" means might be different than yours ;) Please define _exactly_ what a "crash" is in your view. – CouchDeveloper Aug 09 '23 at 09:36
-
I think you can find desired implementation from firebase sources: https://github.com/firebase/firebase-ios-sdk – Cy-4AH Aug 10 '23 at 14:12
1 Answers
-1
If you do not want to use third party solutions, you may use userdefaults, set to "crash" just after the app launch and to "no crash" when cleanly quitting. It will read to crash if and only if the app did not quit cleanly.
Global variables
let keyCrash = "keyCrash
let userDefaults = UserDefaults.standard
ViewDidLoad
in ViewController
let didCrash = userDefaults.value(forKey: keyCrash) as? Bool ?? false
if didCrash {
// handle crash
}
userDefaults.set(true, forKey: keyCrash)
AppDelegate
func applicationWillTerminate(_ application: UIApplication){
userDefaults.set(false, forKey: keyCrash)
}

J Kasparian
- 465
- 2
- 7
-
1Just wrong. An app can quit cleanly without `applicationWillTerminate` being called. In fact, nowadays `applicationWillTerminate` is just about never called. – matt Aug 08 '23 at 12:25
-
-
From what I saw `applicationWillTerminate` is not called only when we move to background and then quit the app. Can you pls throw light on how this is never called, the apple docs are not very helpful? @matt – Keer Aug 08 '23 at 19:40
-
The typical way in which your app stops running is that we move to the background and then the _system_ quits the app. In that case, `applicationWillTerminate` is not called. So that is the most common situation. We did not crash at all; we terminated _in good order_. – matt Aug 08 '23 at 21:22
-
For this I thought I can have crash set to false in `applicationDidEnterBackground` , set it back to true in `applicationWillEnterForeground` so in case user goes to background we automatically make it false to avoid this case. @matt does it sound good now. Additionally I want to look at all the lifecycle methods too to check for false positives. – Keer Aug 09 '23 at 06:07
-
matt is right here. The vexing thing here is – according the [official documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623111-applicationwillterminate) – "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, it may or may not be called. I have to agree, that this is not exactly what we developers expect. alas. – CouchDeveloper Aug 09 '23 at 10:16
-
@CouchDeveloper thanks, as a dev I feel we should have some way of identifying why my past session terminated and not having any info around this is not helpful. In my case I would at least want to get this metrics to perform a few clean ups before allowing the user to enter the normal flow but seems like there is no straight forward way without using 3rd party libraries that can add to my appsize given I am already using one for crash reporting this is going to be difficult :( – Keer Aug 10 '23 at 05:24
-
@Keer if your purpose is to do some internal cleanup, without any visible display to the user, you may accept some amount of false positive. In my experience (I use it to store some state of the app to be restored at next launch), `applicationWillTerminate` is called most of the times. Alternatively, as you mention cleanup, an approach would be not to test for crashes, but for the actual need for cleanup, eg checking if the tmp files to be cleaned up have been left behind by the previous run of your app. – J Kasparian Aug 10 '23 at 09:27