NSTimer Keep counting after app is closed in iPhone - iphone

I have a timer that have to count up to 8 hours (28800 second)
after that it should be released
im wondering how to keep the timer running at the background and/or when application is closed?
this is the NSTimer :
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
and this is my condition :
counter++;
if (counter >= 28800) {
[stopWatchTimer invalidate];
counter =0;
timeLabel.text = #"Time Out";
}

You can't - once your app is closed then it's not running anymore so the timer won't be running either.
Take a look at local notifications?

When application goes in background, In –(void)applicationDidEnterBackground: application delegate method add current counter value and current time in nsuserdefault.
Now when application becomes active before that –(void)applicationWillEnterForeground: will called so in that method get total seconds application was in background ie (current time of application) - (time when application went background which is stored in nsuserdefault) calculate in seconds
so add this also in –(void)applicationWillEnterForeground :
if((seconds calculated) > (28800 - (current counter value stored in nsuserdefault)))
{
// stop timer as it has gone beyond eight hours
}
else
{
// continue task
}

Related

iPhone Countdown Timer For a Selected Duration

I wish to create a countdown timer in my app in such a way that I can give a certain duration (like 15 minutes or 15:00) and it starts on an action.
I also need for that countdown timer to take elapsed time duration and total time duration information from an external web service and start the countdown for the remaining time.
This is actually for a quiz application where the user will be presented with a series of questions and the timer will be placed on the question screen (for the whole quiz and not for only one question). The user can set the duration for the quiz and the countdown timer will begin as soon as the user start taking the quiz. There is also a pause functionality where user can pause the test and the information of time elapsed and total time duration will be registered in a web-service. The user can resume the quiz anytime with the countdown timer starting right from the time it was paused (taking this information from the web-service, that is).
Thanks in advance.
PS: To be honest, I had no idea on how to go about it. There was too much of confusion on what format will the time be stored over in the web-service and a lot of other stuff like if the program will go forward after the NSTimer is running in a loop etc. So you know what I mean. Yes, NSTimer does solve the problem as Alex told and provided with a sample code as well.
Look at the docs for NSTimer.
Generally, you would create an NSTimer which calls a method every second, like so:
NSTimer *theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(tick) userInfo:nil repeats:YES];
Then in tick, you would decrement a variable holding the time remaining, and update a label on the display.
Also, if you want some working sample code, check out my little countdown app on GitHub.
Try these codes, I have already implemented it in my App. Best for resend OTP type functionalities.
int secondsLeft;
int hours, minutes, seconds;
secondsLeft = 60;
[self countdownTimer];
-(void)countdownTimer {
// secondsLeft = hours = minutes = seconds = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
}
- (void)updateCounter:(NSTimer *)theTimer {
if(secondsLeft > 0 ) {
secondsLeft -- ;
hours = secondsLeft / 3600;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft %3600) % 60;
labelSeconds.text = [NSString stringWithFormat:#"%02d seconds left.",seconds];
} else {
[timer invalidate];
return;
}
}

creating a timer for a level in iphone game

Im trying to add a timer to my game so that the user knows how long they have spent playing a level. Ive figured out that I can initialize a timer the following way:
bool showTimer = YES;
NSDate startDate;
UILabel timerLabel; // initialized in viewDidLoad
-(void) showElapsedTime: (NSTimer *) timer {
if (showTimer) {
NSTimeInterval timeSinceStart;
if(!startDate) {
startDate = [NSDate date];
}
timeSinceStart = [[NSDate date] timeIntervalSinceDate:startDate];
NSString *intervalString = [NSString stringWithFormat:#"%.0f",timeSinceStart];
timerLabel.text = intervalString;
if(stopTimer) {//base case
[timer invalidate];
}
}
}
- (void) startPolling {
[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:#selector(showElapsedTime:) userInfo:nil repeats:YES];
}
I start the startPolling method in the viewDidLoad. When I run the app, I do see the timer and it tracks the time but when I exit the app and re-enter it, the timer doesnt pause. I'm also not sure how to handle going to another view (like the options menu) and then coming back to this view. I understand NSDefaults and NSCoding and I see how I could save the current value on the timer as a Coding object, keeping a seperate key-value pair in a plist for every level but this seems cumbersome.
Is there a better way to keep track of how long the user spends in a level?
Instead of doing the calculation (subtracting the start time from the current time) every time, since all you care about is an elapsed time, just have a variable like NSTimeInterval elapsedTime that you start at 0 and add time to every time that the timer fires. (If you want to track it to 0.1 seconds like in your example, just divide by 10 before displaying it.) This way, you can pause it whenever you want and it will just continue on from where it was before when it starts up again.

How to call a countdown timer from 5 second and it should decrement to 1 second in iPhone?

I have an application in which I want that when I run my application initially it should show a screen for 2 seconds that displays warning about the app and just after 2 seconds a countdown should start from 5 seconds that should decrement from 5 second to 1 second.
There are two ways:
[NSTimer timerWithTimeInterval: .....]
[self performSelector: withObject: afterDelay:]
so if i got your point you want to display a warning screen and after 2 seconds you want to show the user count down start from 5 and end at 1 .. well this can done easy by using a timer and counter as following :
define a NSTimer and start it once the warning view is shown .. your definition will be like this:
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timerFires) userInfo:nil repeats:YES];
[timer fire];
define a global integer and set its initial Value to 7 (lets suppose you name it counter).
-in timerFires selector you decreament counter by 1 and check its value when its equal to 5 start to show its vlaue on UILabel for example and when its 1 invalidate the timer and do you what you want at this point .. the timerFires will be like this:
- (void)timerFires
{
counter --;
if(counter ==5)
{
//show its Value
}
if(counter ==1)
{
[timer invalidate];
timer = nil;
//Do other stuff
}
}
[NSTimer scheduledTimerWithTimeInterval:60 target:self selector:#selector(updateFunction) userInfo:NULL repeats:YES];
In updateFunction you can write your code for count down.
You can also set "repeats:NO" and to call the updateFunction at the end of itself if it is necessary

Increase timeInterval of a Timer [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Change the time interval of a Timer
So I have a timer:
timer=[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(createNewImage) userInfo:nil repeats:YES];
And I would like that the timer decrease every ten seconds, that scheduledTimerWithTimeInterval goes to 1.5 after ten seconds then to 1.0 after 10 seconds... Is it possible to do this, and if it is possible, how can I do it?
You can't modify a timer after you created it. To change the timer interval, invalidate the old timer and create a new one with the new interval.
You don't have to use several timers, all you have to do is add a variable to use for the time interval, then create a method that invalidates the timer, changes the variable and starts the timer again. For instance you could make a method that starts the timer.
int iTimerInterval = 2;
-(void) mTimerStart {
timer = [NSTimer scheduledTimerWithTimeInterval:iTimerInterval target:self selector:#selector(createNewImage) userInfo:nil repeats:YES];
}
-(void) mTimerStop {
[timer invalidate];
iTimerInterval = iTimerInterval + 5;
[self mTimerStart];
}
This would be the simple way to decrease the timer interval and keep the timer going, but I would personally prefer using the one below, because it makes sure that the timer has only ran once, that way it will not duplicate the instance, forcing your app to become glitchy and it also makes things easier for you.
int iTimerInterval = 2;
int iTimerIncrementAmount = 5;
int iTimerCount;
int iTimerChange = 10; //Variable to change the timer after the amount of time
bool bTimerRunning = FALSE;
-(void) mTimerToggle:(BOOL)bTimerShouldRun {
if (bTimerShouldRun == TRUE) {
if (bTimerRunning == FALSE) {
timer = [NSTimer scheduledTimerWithTimeInterval:iTimerInterval target:self selector:#selector(mCreateNewImage) userInfo:nil repeats:YES];
bTimerRunning = TRUE;
}
} else if (bTimerShouldRun == FALSE) {
if (bTimerRunning == TRUE) {
[timer invalidate];
bTimerRunning = FALSE;
}
}
}
-(void) mCreateNewImage {
//Your Code Goes Here
if (iTimerCount % iTimerChange == 0) { //10 Second Increments
iTimerInterval = iTimerInterval + iTimerIncrementAmount; //Increments by Variable's amount
[self mTimerToggle:FALSE]; //Stops Timer
[self mTimerToggle:TRUE]; //Starts Timer
}
iTimerCount ++;
}
-(void) mYourMethodThatStartsTimer {
[self mTimerToggle:TRUE];
}
I didn't finish all of the coding, but this is most of what you will need. Just change a few things and you'll be good to go!
You will need a set or sequence of timers, one for each different time interval. Stop/invalidate one timer and start the next timer when you want to change to the next time interval in your time sequence.

Wait for random amount of time, then start updating elapsed time in a UILabel (iPhone)

I'm trying to implement a button that starts a timer after a random period of time (between 0-10s). While the timer is running it should update a label every 0.005s to show how much time has elapsed. The problem i'm having is 2-fold:
I'm not sure how to get the label to update with the elapsed time every 0.005s.
I'm having trouble getting the app to wait the random amount of time before starting timer. At present I'm using sleep(x) however it seems to cause the app to ignore all the other code in the if statement and causes the button image to freeze up (i.e. it looks like its still clicked).
Here is the code I have so far...
- (IBAction)buttonPressed:(id)sender
{
if ([buttonLabel.text isEqualToString:#"START"])
{
buttonLabel.text = #" "; // Clear the label
int startTime = arc4random() % 10; // Find the random period of time to wait
sleep(startTime); // Wait that period of time
startTime = CACurrentMediaTime(); // Set the start time
buttonLabel.text = #"STOP"; // Update the label
}
else
{
buttonLabel.text = #" ";
double stopTime = CACurrentMediaTime(); // Get the stop time
double timeTaken = stopTime - startTime; // Work out the period of time elapsed
}
}
If anyone has any suggestions on..
A) How to get the label to update with the elapsed time.
or
B) How to fix the 'delay' period from freezing up the app
... it would be really helpful as I'm pretty much stumped at this point. Thanks in advance.
You should use an NSTimer to do this. Try the code:
- (void)text1; {
buttonLabel.text = #" ";
}
- (void)text2; {
buttonLabel.text = #"STOP";
}
- (IBAction)buttonPressed:(id)sender; {
if ([buttonLabel.text isEqualToString:#"START"]) {
int startTime = arc4random() % 10; // Find the random period of time to wait
[NSTimer scheduledTimerWithTimeInterval:(float)startTime target:self selector:#selector(text2:) userInfo:nil repeats:NO];
}
else{
// I put 1.0f by default, but you could use something more complicated if you want.
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(text1:) userInfo:nil repeats:NO];
}
}
I'm not exactly sure how you want to update label based on the time, but if you post more code, or give an example, I'll post the code on how to do that, but it would just be using an NSTimer as well. Hope that Helps!
The answer to A could be:
Once the random amount of time has passed, (#MSgambel has a good suggestion), then execute:
timer = [NSTimer scheduledTimerWithTimeInterval:kGranularity target:self selector:#selector(periodicallyUpdateLabel) userInfo:nil repeats:YES];
(The above line could go into #MSgambel's -text2 method.)
That will call the -periodicallyUpdateLabel method once every kGranularity seconds, repeatedly. In that method, you could do things like update your label, check for user actions, or end the game if the time is up or some other condition has been met.
And here is the -periodicallyUpdateLabel method:
- (void)periodicallyUpdateView {
counter++;
timeValueLabel.text = [NSString stringWithFormat:#"%02d", counter];
}
You'll have to format the text differently to get what you want. Also, translate from the counter value to time using kGranularity. However, and this is what I found, there is only so many cpu cycles in iOS devices. Trying to go down to microsecond level made the interface sluggish and the time displayed started to drift from the actual time. In other words, you may have to limit your updates of the label to once every one hundredth of a second or tenths. Experiment.