Does iOS watchdog monitor process while debugger is attached? - ios

I'm debugging a background task issue where my app is being killed by the watchdog when socket data is received too often in the background.
Does the watchdog perform it's operations under the context of a debugger?
My answer is: I do not believe so.

Based on some logs I have seen about apps failing to respond for 10 seconds while paused in the debugger, I would say yes it is watching, but it does not enforce its rules. It simply informs you.

Related

Reasons why iOS will terminate an app

We have a GPS tracking type iOS app which runs in the background. We are seeing infrequent cases where the app appears to be getting terminated with the applicationWillTerminate method being called while the tracking process is taking place.
We have more or less ruled out low RAM as the reasons. Also definitely not a battery level issue or users terminating the app.
Any suggestions what would be the next most likely causes for iOS to terminate the app?
Some thoughts we had were CPU usage, phone temperature level or simply because the app is running in the background for extended periods (e.g. days or weeks).
Are any of these likely or even possible causes for iOS to terminate the app?
From Apple's Background Execution docs:
Do minimal work while running in the background. The execution time
given to background apps is more constrained than the amount of time
given to the foreground app. Apps that spend too much time executing
in the background can be throttled back by the system or terminated.
Also, I assume you've verified you're not running afoul of the below (from the same doc):
Each call to the beginBackgroundTaskWithName:expirationHandler: or
beginBackgroundTaskWithExpirationHandler: method generates a unique
token to associate with the corresponding task. When your app
completes a task, it must call the endBackgroundTask: method with the
corresponding token to let the system know that the task is complete.
Failure to call the endBackgroundTask: method for a background task
will result in the termination of your app.

How to perform some action when device is connected to WiFi and app is terminated?

How should I communicate with server or do some action when my device is connected to the WiFi and my app is terminated (not runnning on background/foreground)?
According to the documentation for UIApplicationDelegate's applicationWillTerminate API (which has a companion UIApplicationWillTerminate notification you can observer), you have approximately five seconds to perform any tasks and return before the app dies.
If this were my problem, I'd be wondering if five seconds is that long enough to reliably talk to the server or do any useful action aside from cleanup.
If your app goes in Terminated state, you can't perform any operation. The thing you could've done is in the Background state. You should go through this Apple Documentation for better understanding on iOS App Lifecycle.

iOS: how to detect when the UIApplicationDelegate state becomes "suspended"?

How can we detect when an iOS App has been suspended?
There is no method that mentions this in the official UIApplicationDelegate documentation.
These are the states that an App can have:
(source: apple.com)
Use case:
I want to log when an app stops running subsequently to being woken up due a location event. For example I have got an iBeacon that the app is montioring. I activate the iBeacon and the app gets launched successfuly in background (for 10 seconds). I would like to detect when the App stops running after these 10 seconds have elapsed. However there is no AppDelegate method that seem to allow to intercept this (please consider that I am investigate this specific case.
Previous question:
I had asked a previous similar question which did not get answered. Please find it here.
While I am unaware of any callback, you can query for the amount of background time remaining with:
NSLog(#"background time remaining: %8.2f", [UIApplication sharedApplication].backgroundTimeRemaining);
Theoretically, you can put this in a thread and execute custom code a second or so before your app terminates. See my blog post here for more info:
http://developer.radiusnetworks.com/2014/11/13/extending-background-ranging-on-ios.html
I think you won't get any feedback form Suspended state. Suspended means that app is in memory but no code is executing right now.
Documentation:
The app is in memory but is not executing code. The system suspends apps that are in the background and do not have any pending tasks to complete. The system may purge suspended apps at any time without waking them up to make room for other apps.
So in my understanding, if an app would give you a callback with something like applicationDidEnterSuspendedState it will be a paradox, cause Suspended state means that no code is executed.

How to periodically wake and check status in iOS?

I want my app to periodically wake and check a status, but burn minimal cycles between wake ups. Is the a Core call for this or an accepted design pattern?
Prior to ios7, apps could only ask for execution cycles in background for a handful of purposes (e.g. playing sound or getting location updates). While they added more options in ios7, like periodically fetching data from a server, I'm still not clear there is a way to do this. (It's also a bit difficult for me to imagine why your app cares about battery if it isn't running, but maybe that is my failure of imagination.) Recommend reading Background Execution and Multitasking in the AppleDocs.

Will iOS kill my app if it becomes unresponsive?

I'm developing an iOS app for an office lobby installation. The app will only be installed on six iPads, and won't ever be distributed via the app store. The app will need to download a large content file once a day, and any time it's restarted. Also, the app will need to preload a bunch of images so they can be displayed quickly. This whole process takes a while -- 45 seconds or so. It's long enough so that the os kills the app on startup. I've deferred the loading process until after startup, which seems to work.
What I'm wonder now is whether I might run in to another OS-imposed time constraint, where if an iteration of the run loop takes too long to return (and the OS observes the app as being unresponsive) it kills it. Does such a constraint exist? Or, for my specific case, where I don't need to worry about annoying users with an unresponsive UI, can I safely take as long as I want to execute a task on the main thread, once the app has started.
Yes. The watchdog will kill your app if you block the main thread and the application takes too long to respond to system events. I don't believe that Apple state an actual time though.
More information here https://developer.apple.com/library/ios/#technotes/tn2008/tn2151.html or google 0x8badf00d. This is the exception code associated with a watchdog timeout.
Technically, you can run long-running task synchronously once the app has been launched if your users don't mind waiting for an unresponsive UI. However, a user may lock their device and unlock it later. If your app will fail to respond to application life-cycle callbacks (applicationWillResignActive: and applicationDidBecomeActive:) it still might get killed.
See this Q/A for technical information about the iOS watchdog -- a daemon process that makes sure that apps behave well.
Note that when you launch your app from Xcode, watchdog won't kill it no matter what. But once you've launched your app from the Home screen, watchdog takes over it. It has nothing to do with App Store actually.
To be safe, I would suggest you to perform long-running tasks in a background thread. This is very easy to do with [self performSelectorInBackground:withObject:]. And you can show an activity indicator or even display the number of downloaded files in the UI so that users know something is working under the hood.
To update UI from the background thread, you have to call to the main thread to execute the update code. It can be done like this:
- (void)methodRunningInBackground
{
// some work is done here ...
dispatch_async(dispatch_get_main_queue(), ^{
// update your UI here
});
}

Resources