NSTimers running in background? - iphone

I was under the impression that NSTimer did not work at all after an application calls applicationWillResignActive. I seems however that existing NSTimers (i.e. ones created before the application resigned active) will continue to run and its only new NSTimers that can't be scheduled in this state, can anyone confirm this?
I am also assuming that its good (and Apple seems to say this too) that when your application calls applicationWillResignActive you should disable any NSTimers and start them again when applicationDidBecomeActive is called, does that make sense?

When an application is inactive, but still in the foreground (such as when the user gets a push notification or presses the sleep button) your application is still running completely. Any timers you have created which you don't stop will fire as normal. However, when your application goes to the background, if you are not registered to run a background thread all execution is stopped. If it is time for a timer to fire, it will not happen because the run loop is not running. When your application is reopened, however, any timers which were supposed to fire while it was in the background will all be fired immediately. Apple suggests doing cleanup in applicationWillResignActive so that you are not doing a lot of work when the user is not focused on your application, but you definitely want to disable timers before going to the background so that they don't all fire one after the other when your application is reopened.

Related

Can we stop the for loop when app goes background

The for loop is running fetching the data(images and text) from array but when i press home screen button the loop still continues in background and lasts more than 5 seconds which is default time, it should not be more that that as i studied while googling. And when i press home button even then the app delegates respective method like appEnterBackground also called after completion of this loop containing method. So, is it possible to break the loop when the home button is pressed.
Please guide.
If you wanted to detect the entering into background, in addition to responding to the app delegate applicationDidEnterBackground method, you could alternatively register yourself as an observer of the UIApplicationDidEnterBackgroundNotification notification (e.g., using the addObserverForName method of [NSNotificationCenter defaultCenter]).
Note, if you want to cancel your requests, you will want to ensure that (a) the requests are run asynchronously; and (b) they're cancelable. If you're targeting iOS 7 and later, you can accomplish this with NSURLSession (e.g., dataTaskWithRequest or dataTaskWithURL which return a NSURLSessionDataTask object, on which you can call the cancel method if and when desired). Then you can write a handler for the notification that cancels any pending requests.
If you really want to cancel the requests, you can do something like the above, but you alternatively could simply request additional time to complete the requests if the app happens to go into background while the requests are running. This way you get a few minutes to finish requests rather than just a few seconds. See Executing Finite-Length Tasks in App Programming Guide for iOS: Background States.
Or, perhaps even better, you could add your tasks to a background NSURLSession. See the Downloading Content in the Background section of the aforementioned App Programming Guide for iOS: Background States. This way the tasks will continue even after your app is suspended (or, if you app is terminated due to memory pressure). For more information, see WWDC 2013 video, What's New in Foundation Networking.

iOS applicationWillEnterForeground not called and black screen while background task is running

I'm using a background task to complete a few operations when the user suspends my app.
This works fine, but I just noticed that if the user reactivates the app before the background task is finished the screen stays black and applicationWillEnterForeground: is never called.
Once the background task is done all is fine again and applicationWillEnterForeground is called, but is there a way to make the app reactivate while the task is running?
All I could find is to have the background task constantly check the remaining time and notice that this becomes very high when the app is reactivated. It can then end itself and the app appears, but this still means the app is black for half a second or so.
Quick question. Are you using beginBackgroundTaskWithExpirationHandler?
And are you running the actual work asynchronously? As shown in this answer?
objective c - Proper use of beginBackgroundTaskWithExpirationHandler
If not, you should run your long running work on a-sychornously because else it will be executed as part of your main RunLoop. Which will indeed block your apps redraws and responsiveness until the long running task is completed.

How to prevent app/game from crashing upon resume after while

My game made using cocos2d crashes on iOS5 after resuming from the background when left for a while. I want to know what the standard/best practice is, on handling an app that is sent to the background. Do I terminate it after a certain time? I see some games pull up a loading screen when you resume it after a long time but when you resume it immediately it goes straight to the game. What are they loading when they resume?
Any pointers in the right direction would be much appreciated.
Thanks
AC
You can opt out of background execution by adding UIApplicationExitsOnSuspend to your Info.plist.
Other than that it really is your job to ensure that your app doesn't crash when it resumes execution. You have to understand that your application basically enters a suspended state. That means it should unload all unneeded resources, otherwise the system may terminate your app's process.
In your app delegate you should respond to the applicationDidBecomeActive message and respond accordingly so that your app is able to resume execution without any issues. This can include loading any unloaded assets and checking if system settings (ie. locale, Game Center user, etc.) have changed.
You can also register a didBecomeActive UINotification so that any class in your app gets notified when the app should resume.

Running code in a timer while application is in the background

Is it possible for this situation to happen:
My application enters the background, I want a NSTimer to run in the
- (void)applicationDidEnterBackground:(UIApplication *)application
method, every two or so seconds. I know how to initiate the timer, however what I want to know is if I can run code every 2 seconds or whatever I choose in the background? Or is it once the application has entered the background code cannot be run. I know with android if applications are left open but minimised you can run code as they continue to run in the background.
You've doubted it correct. The application that enters background can not run. So, you can not execute your code while the app in background. I'd suggest you to go through the Apple's doc Executing Code in the Background. It begins with,
"Most applications that enter the background state are moved to the suspended state shortly thereafter. While in this state, the application does not execute any code and may be removed from memory at any time."
But the services audio, location and voip are allowed to run in background. For those services the background execution must be declared in advance by the application that uses them.
If you move your application to background and declare the application as audio it will run.

Can I cancel the method "applicationDidEnterBackground?

I wanted to cancel the method, to request a confirmation from the user when he presses the button "HOME" where on iPhone would go into the execution in background.
If the user accepts, enters into the execution in background, if not accept, I do not do anything.
I looked in the FORUM, in the documentation from Apple and I found nothing.
Could anyone help me?
Thanks in advance!
No you can't override this. The event will always fire but it does give you time to clean up before you move to the background.
Your delegate’s applicationDidEnterBackground: method has approximately five seconds to finish
any tasks and return. In practice, this method should return as quickly as possible. If the method does not
return before time runs out, your application is terminated and purged from memory. If you still need more
time to perform tasks, call the beginBackgroundTaskWithExpirationHandler: method to request
background execution time and then start any long-running tasks in a secondary thread. Regardless of
whether you start any background tasks, the applicationDidEnterBackground: method must still exit
within five seconds
iOS Application Programming Guide
No, you can't override the operating system or the user's button press.
If the user presses the button to send the app into the background, the app goes into the background.