NStimer stopped at middle - ios

I am doing one application.In that,i am calling one method for every 10 seconds using the timer.But after sometime that method is not calling. So,may i know the reason for why timer is stopped.

If there is a ScrollView scrolling, the timer in NSDefaultRunLoopMode will be stopped.
You can use this to fix it:
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

If you are checking Timer in Foreground and background, Timer will work continuously in foreground, But in background it will work only 10 mins, After that timer will not work.

Related

Scheduled NSTimer's selector called with delay in iOS

I have an NSTimer that should be running all the time the app is active. It is intended to show a countdown that depends on certain user's actions. I fire this timer this way:
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(notifyTimerTick:)
userInfo:nil
repeats:YES];
Then, in the method notifyTimerTick:, I update the countdown label I show to users and, if the countdown is over, I invalidate the timer, I look for a new countdown, and I fire the timer again.
I'm not having troubles being the UI blocked doing this way, but on the other hand, I've found that sometimes the notifyTimerTick: selector call is significantly delayed: I have a view that takes a couple of seconds to be completely loaded, and I've seen that timer's selector is not called until the corresponding view controller's viewDidLoad delegate method is called.
I've read several posts dealing with timers blocking the UI, but I'm not sure how to deal with a timer getting blocked by the UI... what the best way to handle this should be?
Thanks in advance
You need to use a different run loop mode.
When you use the ScheduledtimerWithTimeInterval class method, the timer is scheduled on the current run loop.
Instead do something like this:
NSTimer *labelTick = [NSTimer timerWithTimeInterval:1 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:labelTick forMode:NSRunLoopCommonModes];

Running an already running NStimer in Background

In my iOS application I am using NSTimer to to record some events happening in my app. Now I want to keep them recording when my app goes to the background so that even if my app is in the background, my NSTimer will continue to record the events.
Can somebody guide me how I can achieve this behaviour?
Unless you enable one of the Background modes, it is not gonna work.
Why?
You have around 10 minutes of background execution after this the timer is stopped by ios.
The timer will not fire after app is locked (iOS7), since ios suspends the foreground app and bgTask will not get fire again.
There is some workarounds, consider to check below
// NSTimer run when app in background
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
loop = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:#selector(Update) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:loop forMode:NSRunLoopCommonModes];
Anotherway check this NSTimer in Background
Timers can not run in background. The only thing you can do is, record the time when application goes into background and when application comes into foreground. Take the difference and do the appropriate action.

Make the ios app working in background

I'm using the pitch detection code from demetri miller demetri miller pitch detection in my application. I want the microphone to work in background and give a UILocalNotification on a particular pitch.
How to make the application run in background.
Currently when the app is in background is there way to make it work fully.
Use the NSTimer when app is going from foreground to background start NSTimer and every one second your timer method will call and you can check the application state. you can execute every thing fine.
NSTimer *timerBackground = [NSTimer timerWithTimeInterval:1.0
target:self
selector:#selector(YourMethod:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timerBackground forMode:NSDefaultRunLoopMode];

how to prevent an NSTimer to be delayed or interrupted by user interface actions in iOS 5

How can I prevent a NSTimer from being delayed by the user scrolling a table?
I found the answer:
I had a timer that repeated about 8 or 9 times with intervals of 0.4 to 0.8 seconds. I don't need much precision, but if the user scrolls a table the timer would stop working until the table finished scrolling (this could be a few seconds wait!). I thought I needed background threads, but timers on background threads were somewhat complicated to implement.
The answer to my problem was very very simple and easy. I just need to add a line after invoking the timer:
//////////// start the timer
self.playingTimer = [NSTimer scheduledTimerWithTimeInterval:tempo target:self selector:#selector(playSoundFromArray:) userInfo:nil repeats:YES];
//////////// the magic line:
[[NSRunLoop currentRunLoop] addTimer:self.playingTimer forMode:UITrackingRunLoopMode];
Now I can scroll the table as much as I want and my timers work OK!!!
Now I need to study a little more NSRunLoop...
You should add your timer for NSDefaultRunLoopMode mode. UITrackingRunLoopMode is used by tracking UI actions(in your case scrolling).

Is NSTimer expected to fire when app is backgrounded?

I don't understand it at all but NSTimer in my app definitely is running in background. I have a NSLog in method run by the timer and it is logging while it's in background. It's on iPhone 4 with iOS 4.2.1. I have declared location background support in Info.plist.
I read the docs and many discussions here and elsewhere and it shouldn't be possible. Is it an iOS bug? Or undocumented feature? I don't want to use it and find out in near future, for example with coming of iOS 4.3 that Apple silently "fixed" it and the app won't be working.
Does anybody know more about it?
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.
You can have a timer fire while in background execution mode. There are a couple of tricks:
You need to opt into background execution with beginBackgroundTaskWithExpirationHandler.
If you create the NSTimer on a background thread, you need to add it to the mainRunLoop manually.
- (void)viewDidLoad
{
// Avoid a retain cycle
__weak ViewController * weakSelf = self;
// Declare the start of a background task
// If you do not do this then the mainRunLoop will stop
// firing when the application enters the background
self.backgroundTaskIdentifier =
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundIdentifier];
}];
// Make sure you end the background task when you no longer need background execution:
// [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Since we are not on the main run loop this will NOT work:
[NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(timerDidFire:)
userInfo:nil
repeats:YES];
// This is because the |scheduledTimerWithTimeInterval| uses
// [NSRunLoop currentRunLoop] which will return a new background run loop
// which will not be currently running.
// Instead do this:
NSTimer * timer =
[NSTimer timerWithTimeInterval:0.5
target:weakSelf
selector:#selector(timerDidFire:)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer
forMode:NSDefaultRunLoopMode];
// or use |NSRunLoopCommonModes| if you want the timer to fire while scrolling
});
}
- (void) timerDidFire:(NSTimer *)timer
{
// This method might be called when the application is in the background.
// Ensure you do not do anything that will trigger the GPU (e.g. animations)
// See: http://developer.apple.com/library/ios/DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW47
NSLog(#"Timer did fire");
}
Notes
Apps only get ~ 10 mins of background execution - after this the timer will stop firing.
As of iOS 7 when the device is locked it will suspend the foreground app almost instantly. The timer will not fire after an iOS 7 app is locked.

Resources