App Crashes But No TestFlight Crash Report - iphone

I have one user (with an iPhone 5) reporting that my app crashes on launch about 15 seconds after the screen goes black (the splash screen is black). The user downloaded a TestFlight build where I included checkpoints in the App delegate, but I don't get evidence that those checkpoints are crossed, and I never get a crash report.
I changed the entry point on the storyboard to a blank view controller, and now I can see that the checkpoints are being crossed. It's occurred to me that Watchdog is suspending the app due to storyboard resources taking too long to load, but all the images are built in real-time as needed, with the exception of four tiny tab-bar icons. There are several audio files but they are loaded on demand. I can't think of any other resources that could be causing a delay. No one else has reported this problem, and I'm stumped.
Any insight appreciated, especially as to why I'm not seeing a crash report or checkpoints from TestFlight.

Your assumption is correct, the watchdog killed the app. This is because the app doesn't start up properly and either the main thread is blocked or no user interaction is possible since no UI is loaded.
As I understand your description, you are creating the resources while loading? And probably doing this on the main thread? You should try to offload resource hungry code into a background thread instead of doing this on the main thread where older/slower devices could take much longer than expected. The UI should always be responsive, the main thread should never ever to tasks that could get anywhere close to one second of processing.
Another reason could be that the link between the storyboard and the view controller is broken and it actually never loads on that device type.
But without more details it is impossible to say what exactly is going on.
In general: If the app is killed by the iOS system, e.g. by the watchdog due to startup time exceeding or due to allocating too much memory, then only iOS can generate a crash report.
The problem is that the app gets killed and in that case the process is killed. And that cannot be detected by any code running inside that process. And since crash reports on iOS, other than the iOS system based crash reporter, do run inside the same app process that is being killed, they cannot report or write any crash report.
The following page gives some more details on this: http://support.hockeyapp.net/kb/how-tos-faq/which-types-of-crashes-can-be-collected-on-ios-and-os-x (Though with context to PLCrashReporter, which is not used by Testflight. But the general statements are identical)

Related

iPhone iOS what is the most accepted way of dealing with memory warnings?

I've been surprised that iOS 5.1 does not manage memory quite as I expected. When the device is running a lot of apps, it appears that iOS does not kill memory hogging apps in the background, but sends memory warning to my own app as well.
For example showing a UIImagePicker crashed the app on two test devices. Double tapping the home key and killing some of the background apps prevents the app from receiving the memory warning and crashing.
I'm wandering if iOS would not free up memory for me, is it acceptable to show some sort of alert view notifying the user that the memory is low and some of the background tasks have to be killed?
I'm at a loss of how to deal with such events - does it take time for iOS to clean up some memory (while apps respond to memory warnings)?
iOS does a lot of stuff before bothering you with memory warnings, including killing backgrounded Apps. Since iOS 5, iOS is even going to annoy you as less as possible with memory warnings, meaning that you only get one if there really is a need for you to get rid of stuff that is using memory but not needed right now (and that you can safely recreate in the future without taking hours for it). If your App crashes without giving you a memory warning first, chances are that you allocated so much memory that the system can't tell you that its running out of memory before it decides to kill you, the reason for this is that the memory warning is scheduled on the runloop of the main thread and until you give the runloop time to do another iteration, you won't receive the warning.
Also, Apple doesn't like you to tell the user that there is a memory problem; Its your App that has to deal with it, not the user! So its very very likewise that your App gets rejected if a memory warning comes up while the review team is reviewing your app (rumor says that they send these warnings to test how your App reacts to them)
Soo, to sum it up: iOS does work like you expected by killing what it can and even shutting down other system daemons, only after this happening you will be notified that memory is low. The correct way to respond to these warnings is to free up as much memory as you can, start with the big stuff that can be easily recreated in the future (eg. if your app shows loads of pictures but not all are visible at a time, throw away the ones that aren't visible right now). Telling the user is the wrong way to deal with the problem and Apple doesn't like it, so try to solve the problem on your end.

App behaviour when an iOS device is restarted(with the app running)

I am facing a weird problem. My iPhone app is password protected and only after entering the correct password, can the user be logged in again. Also the app has multiple screens.
Suppose I am on a particular screen(after logging in) and switch off the device(with app still running), switch on the device back and launch my application, it starts back from the screen which was visible when the device was restarted. The password screen is not shown, and it seems like applicationDidFinishLaunching was never called. When I kill the app from background and start it again, it works normal.
Wouldn't the app loose all data in memory when the device is restarted? Wouldn't the views will have to be drawn again? How exactly does an app behave in this case.
EDIT:
I did what TriPhoenix has suggested. What I observed is that if you switch on the device and launch the application very soon, the applicationDidBecomeActive delegate method doesn't get called. However if you give it some time before launching, everything seems to work as expected. Isn't the applicationDidBecomeActive method supposed to be called with every app launch?
What I am testing on:
OS: iOS 5.0.1
Xcode: 4.2.1
Device: iPhone 4s
Is it possible that your app is very small in terms of memory usage? I remember a WWDC talk (cannot find the right one right now unfortunaly) where it is told that very small apps in terms of memory usage (a limit is not publicly defined but I think it was around 16 MiB memory usage) are not killed on low memory conditions but rather suspended to the phone's flash memory to be awakened later. I'm not sure if this is designed to survive a complete shutdown but it would sure be one of the few possibilities. To check this you could try to artificially increase your memory usage by creating some large objects / arrays and see if the problem disappears.
In any case there might be better functions to reactivate the password protection, e.g. applicationWillEnterForeground: or applicationDidBecomeActive: as this should cover all possibilities where the user might return to your app.

iOS: Prevent a background location service from getting unloaded when the system sends a low memory warning

I've got a location service running in the background, but I'm finding that sometimes if the user runs a number of other apps in the foreground my app will get unloaded.
Using Instruments my app currently consumes about 1.2MB in the background. A project with an empty view consumes about 600KB in the background. I know I have some improvements that can be made to bring this closer to the minimum, but beyond that is there anything else I can do to prevent my app from getting unloaded? Since my app is actually doing something "useful" in the background, is there a way to indicate this to the system so that my app will get preference some other suspended app like a game which doesn't need that memory?
Does anyone know how the algorithm works in terms of which background apps are flushed first? Is it by order of memory usage, by oldest open app in the foreground, by oldest run thread in the background?
To expand on the question:
What are the right trade-offs to be made in this service scenario? I can move my CLLocation into the AppDelegate. Should I force my ViewController to unload every time it enters into the background, such that my background memory usage is the absolute minimum, but trading off start-up time and forcing a reload of cached map tiles? Or can I wait until I get the didReceiveMemoryWarning before releasing the viewController?
If I had some sense of the order in which apps will be killed that would help to make the right trade-offs. For instance is there a round robin approach where the oldest suspended app gets the warning first. Then on coming around again if the system still needs more memory it does the actually killing? Or does the system issue the memory warning to an app, sees that not enough has been freed and than kills the app, then moves onto the next suspended app. Or is the order by memory usage?
Any best practices in on this subject would be appreciated.
Update:
After spending half a day converting my app from ARC & Storyboard back to to manual allocation, I still found that the background memory usage was roughly the same. Even though I removed all view controllers from the view and released them, the system still doesn't free that memory immediately. So in the end my app was just as likely to be killed as it was when I was using ARC. What's more interesting is that my app never gets a didRecieveMemoryWarning and my viewDidUnload never gets called, my app just gets killed without notification.
Luckily it was pointed out to me in the Apple Developer forum that if MonitoringSignificantLocationChanges is enabled even if my app is killed it will get reloaded on a significant location change.
I just had to be cognizant that my app could be re-launched from the background and had to use [[UIApplication sharedApplication] applicationState] to handle that event accordingly.
Well you can't stop iOS from killing your app, that's just the way the system works.
If there is a memory low memory warning iOS will kill the some of the apps that are running in the background.
Tips are just keep your memory usage as low as posible.

Core Data lightweight migration crash

I updating my database with a lightweight migration. If I do the update on my device through xcode in debug mode everything runs fine. If I load the app through iTunes as a archive file it will crash before loading the rootViewController. This only happens with my large test database >100mb. I don't get anything useful in the crash log and am not sure what to do with this.
His is the only relevant line I can find in the crash log.
Unknown thread crashed with unknown flavor: 5, state_count: 1
Normally this would be reflected in the crash report (It would say something about failing to launch in time) but iOS devices expect you to get a view on the screen (or for ApplicationDidFinishLaunching to finish, I'm not sure exactly what it looks for) in a certain amount of time or it just gives up and closes the app. If you are doing a significant amount of work you'll want to get some kind of screen up before you start that work. Unfortunately this doesn't happen in a debug environment so it's a pain to test.

startup screen sometimes showing when resuming - does this indicate a potential memory issue with my iphone app?

I have an iPhone application I'm testing - I've just noted when testing it on a device that sometimes when I resume it (i.e. launch it again in the "multitasking" sense when I expect it to appear and continue on) the startup image appears. As if it totally restarted.
Would this be an indication of memory issue with the app?
Good question. I've noticed this as well and wondered also. It might not be this app that has an issue though, but other apps have required extra memory which caused the system to take memory from this app. Im not sure exactly because (if I recall correctly) the resumed app restarts on the screens it was on, so it didnt lose state. I wonder if in this case, iOS has unloaded some of the backgrounded task's code and its taking a bit of time to read the code back in, so it puts that screen up. However, if this was the case, then the app would really need to be idle and not active in the background.