Is Nstimer Expected to Fire When App Is Backgrounded

Is NSTimer expected to fire when app is backgrounded?

NSTimer is going to fire whenever the main runloop is running. Apple makes no promises that I know of to unschedule timers or to prevent the main runloop from running. It's your responsibility to unschedule your timers and release resources when you move to the background. Apple isn't going to do it for you. They may, however, kill you for running when you are not supposed to or using too many seconds.

There are many holes in the system that will allow an app to run when it isn't authorized to. It would be very expensive for the OS to prevent this. But you cannot rely on it.

What is an NSTimer's behavior when the app is backgrounded?

You observed correctly how an NSTimer behaves.

If you create a timer right now that should fire every ten minutes, it will try to fire ten minutes, 20 minutes, 30 minutes and so on from now. If the app goes to sleep after one minute and wakes up after 12 minutes, the timer will fire immediately, and then again at 20 minutes (not ten minutes after the timer firing, but 20 minutes after the original time).

But if the timer misses one event completely and then is late for the next timer event as well, say if you wake up after 29 minutes, then the 10 minute event is dropped, the 20 minute event is fired as soon as possible (after 29 minutes), and the 30 minute event is fired after 30 minutes.

Is NSTimer expected to fire when app is backgrounded?

NSTimer is going to fire whenever the main runloop is running. Apple makes no promises that I know of to unschedule timers or to prevent the main runloop from running. It's your responsibility to unschedule your timers and release resources when you move to the background. Apple isn't going to do it for you. They may, however, kill you for running when you are not supposed to or using too many seconds.

There are many holes in the system that will allow an app to run when it isn't authorized to. It would be very expensive for the OS to prevent this. But you cannot rely on it.

Scheduled NSTimer when app is in background?

You shouldn't solve this problem by setting a timer, because you're not allowed to execute any code in the background. Imagine what will happen if the user restarts his iPhone in the meantime or with some other edge cases.

Use the applicationDidEnterBackground: and applicationWillEnterForeground: methods of your AppDelegate to get the behavior you want. It's way more robust, because it will also work when your App is completely killed because of a reboot or memory pressure.

You can save the time the timer will fire next when your App is going to the background and check if you should take action when the App comes back to the foreground. Also stop and start the timer in this methods. While your App is running you could use a timer to trigger the update at the right moment.

NSTimer behavior on background/foreground

It seems to me that when the app is foregrounded, the timer actually looks at the elapsed time since background, determines the number of times it should have fired in between, and fires them all. I observed this scenario happening both on iOS 7 simulator and iOS 7 iphone.

That is a correct description of the behavior of NSTimer and the run loop. When your app is suspended it won't fire (by default, when you background it; but if you start a background task, it will fire as normal while the task is running).

Keep running NSTimer switching Background and Foreground

Instead of trying to maintain an NSTimer in the background (which is impossible beyond about 10 minutes), what you want to do is record when your timer started and save that in NSUserDefaults. You can still update your timer every second, but just recalculate the label based on the start time (remember, NSTimer doesn't promise that it will run on time; it could be late for many reasons and you'll drift).

Now there is no reason to run in the background. When your view controller comes onscreen (viewDidAppear:), just update the label again, based on the start time saved in NSUserDefaults.

There is no way in iOS to run indefinitely in the background. That's by design. But there's also no reason for you to be wasting system resources trying to update your UI when you're not onscreen. Just update it when you are.

NSTimers running in background?

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.

Difference in scheduling NSTimer in main thread and background thread?

NSTimer requires an active run loop, when initialized in Main Thread it automatically uses the main run loop. If you need to make a background timer you need attach it to the thread’s run loop and invoke run() to make it active.

  1. NSTimer needs one live NSRunLoop to execute it’s events. In main thread, the NSRunLoop is always live and will never stop until the app is terminated, but in other threads, you must invoke run() to active the NSRunLoop.

  2. NSTimer must invoke invalidate() to release the current timer, otherwise, the timer will retain a strong reference of the current instance of target, and it will remain in memory until invalidate() invoked or app terminated;

  3. NSTimer must created and invalidated in the same thread, and a lot of times, we may forget that.

Take a look at this example , it may be helpful >> http://www.acttos.org/2016/08/NSTimer-and-GCD-Timer-in-iOS/
and the documentation : https://developer.apple.com/documentation/foundation/nstimer



Related Topics



Leave a reply



Submit