Objective C : NStimer- How to stop timer after n hours - objective-c

I have started the timer using below call, and need to stop it after n hours
self.timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:#selector(sendLocationUpdates) userInfo:nil repeats:YES];
The solution I can thin of get the current time when timer start and keep adding time till threshold reaches. Or is there any better way to stop timer?

Add an instance variable to the class to store the start time of the timer:
YourClass.m:
#interface YourClass () {
NSTimeInterval _startTime;
}
#end
Record the current time when creating the timer:
self.timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:#selector(sendLocationUpdates) userInfo:nil repeats:YES];
_startTime = [NSDate timeIntervalSinceReferenceDate];
and test the current time in the sendLocationUpdates method:
#define TIMER_LIFE_IN_SECONDS 3000.0
- (void)sendLocationUpdates
{
// do thing
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (now - _startTime > TIMER_LIFE_IN_SECONDS) {
[self.timer invalidate];
self.timer = nil;
}
}

simple solution
declare two properties
#property NSInteger counter;
#property NSTimeInterval interval;
set the counter to 0 before starting the timer
self.counter = 0;
self.interval = 20.0;
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.interval target:self selector:#selector(sendLocationUpdates) userInfo:nil repeats:YES];
in the sendLocationUpdates method increment the counter
- (void)sendLocationUpdates
{
counter++;
if (counter == 4 * (3600 / self.interval)) {
[self.timer invalidate];
self.timer = nil;
}
// do other stuff
}
with a given time interval of 20 seconds the timer fires 180 times per hour.
In the example the timer stops after 4 hours

Related

Why NSTimer sends positions every 5 seconds instead of every 60?

Why NSTimer sends positions every 5 seconds instead of every 60?
- (void)startTimer {
self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0
target:self
selector:#selector(sendPosition)
userInfo:nil
repeats:YES];
}
- (void)stopTimer {
if(self.timer){
[self.timer invalidate];
self.timer = nil;
}
}
I suspect that there are multiple timers created due to multiple firing of startTimer function. To ensure that there is only one instance of such timer, you can implement the following.
- (void)startTimer {
// stop and remove timer first if it is already there
if(self.timer){
[self.timer invalidate];
self.timer = nil;
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0
target:self
selector:#selector(sendPosition)
userInfo:nil
repeats:YES];
}
This way, no matter how many times the startTimer was called,there is only one instance of it.

Stop Method Execution after 5 Minute

How can i stop the execution of the method after a certain time?
I am calling method as below:
[NSTimer scheduledTimerWithTimeInterval:5.0f
target:self
selector:#selector(doSomeTask) userInfo:nil repeats:YES];
Here i have given interval of 5 Seconds. So this method will get called after every 5 seconds, So once the reaches to specified time i want to stop this method execution.
Take a counter variable, and increase in every call by 5 (as time interval is 5 sec ) like
counter = counter+5;
-(void) doSomeTask {
if (counter<=60) { // 5 min = 300 300/5 = 60
// Write method body here
counter = counter+5
}
else {
[timer invalidate];
}
}
If you want to stop execution of the method after 5 min. Then you can add code like this
#interface YourClass () {
int count;
}
#end
-(void)viewDidLoad {
count = 5;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(doSomeTask) userInfo:nil repeats:YES];
}
-(void) doSomeTask
{
count = count + 5;
if (count==300)
{
[timer invalidate];
timer=nil;
}
}
#define TIMER_LIFE_IN_SECONDS 300.0
#interface YourClass () {
NSTimeInterval _startTime;
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(doSomeTask) userInfo:nil repeats:YES];
_startTime = [NSDate timeIntervalSinceReferenceDate];
- (void) doSomeTask
{
// do thing
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (now - _startTime > TIMER_LIFE_IN_SECONDS) {
[self.timer invalidate];
self.timer = nil;
}
}
you can try like this
NSTimer *reachTimer;
NSInteger secondsLeft;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
secondsLeft = 0;
reachTimer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
}
-(void)updateCounter:(NSTimer *)theTimer{
secondsLeft = secondsLeft+5;
if(secondsLeft>=300) // 60sec * 5min= 300
{
[reachTimer invalidate];
}
}
Try this;
int count;
NSTimer *timer;
-(void)startTimertillLimit:(int)limit {
count = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:#selector(doSomething:)
userInfo:[NSString stringWithFormat:#"%d",limit]
repeats:YES];
}
-(void)doSomething:(NSTimer*)sender
{
int limit = (int)[sender.userInfo intValue];
count = count + 5;
if (count > limit)
{
[timer invalidate];
timer=nil;
count = 0;
}
}
Try to create NSTimer that will be called after some time only once :
NSTimer *previous [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(doSomeTask) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:300 target:self selector:#selector(stopPrevious) userInfo:nil repeats:NO];
-(void)stopPrevious{
[previous invalidate];
}

how to finish my countdown timer in objective c?

I have a countdown timer where the user can input the time they want to start from using a countdown timer like in the clock app. The problem is, I can't figure out how to make the timer actually count down. I have already made the UI and have most of the code, but I don't know what would go in the updateTimer method I have. Here is my code:
- (void)updateTimer
{
//I don't know what goes here to make the timer decrease...
}
- (IBAction)btnStartPressed:(id)sender {
pkrTime.hidden = YES; //this is the timer picker
btnStart.hidden = YES;
btnStop.hidden = NO;
// Create the timer that fires every 60 sec
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
- (IBAction)btnStopPressed:(id)sender {
pkrTime.hidden = NO;
btnStart.hidden = NO;
btnStop.hidden = YES;
}
Please let me know what goes in the updateTimer method to let the timer decrease.
Thanks in advance.
You would track the overall time left with a variable. The updateTimer method will be called every second, and you would reduce the time left variable by 1 (one second) each time updateTimer method is called. I have given an example below, but I have renamed updateTimer to reduceTimeLeft.
SomeClass.h
#import <UIKit/UIKit.h>
#interface SomeClass : NSObject {
int timeLeft;
}
#property (nonatomic, strong) NSTimer *timer;
#end
SomeClass.m
#import "SomeClass.h"
#implementation SomeClass
- (IBAction)btnStartPressed:(id)sender {
//Start countdown with 2 minutes on the clock.
timeLeft = 120;
pkrTime.hidden = YES;
btnStart.hidden = YES;
btnStop.hidden = NO;
//Fire this timer every second.
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(reduceTimeLeft:)
userInfo:nil
repeats:YES];
}
- (void)reduceTimeLeft:(NSTimer *)timer {
//Countown timeleft by a second each time this function is called
timeLeft--;
//When timer ends stop timer, and hide stop buttons
if (timeLeft == 0) {
pkrTime.hidden = NO;
btnStart.hidden = NO;
btnStop.hidden = YES;
[self.timer invalidate];
}
NSLog(#"Time Left In Seconds: %i",timeLeft);
}
- (IBAction)btnStopPressed:(id)sender {
//Manually stop timer
pkrTime.hidden = NO;
btnStart.hidden = NO;
btnStop.hidden = YES;
[self.timer invalidate];
}
#end

Objective C How do I make a timer that counts down from two minutes?

I searched around the internet for an answer but with no luck. I tried
- (void)viewDidLoad {
[super viewDidLoad];
twoMinTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timer) userInfo:nil repeats:YES]; }
- (void)timer {
for (int totalSeconds = 120; totalSeconds > 0; totalSeconds--){
timerLabel.text = [self timeFormatted:totalSeconds];
if ( totalSeconds == 0 ) {
[twoMinTimer invalidate];
} } }
but it didn't work, the label went from 2.00 to 0.01 when I went to that view and then it just stopped.
Any advice would be greatly appreciated
- Philip
You're using a one off for loop instead of simply decrementing the total amount of time. Try this:
- (void)viewDidLoad {
[super viewDidLoad];
totalSeconds = 120;
twoMinTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timer)
userInfo:nil
repeats:YES];
}
- (void)timer {
totalSeconds--;
timerLabel.text = [self timeFormatted:totalSeconds];
if ( totalSeconds == 0 ) {
[twoMinTimer invalidate];
}
}
Declare totalSeconds as an int.
EDIT: My absolute thanks for #JoshCaswell and #MichaelDorst for the suggestions and code formatting respectively. NSTimer is in no way an accurate representation of time, and is definitely not accurate enough for a stopwatch or counter. Instead, NSDate's +dateSinceNow would be a more accurate substitute, or even the progressively lower level CFAbsoluteTimeGetCurrent() and mach_absolute_time() are accurate to sub-milliseconds

NSTimer code is executing forever

Here is my code. I expected the timer to stop in 5 second after it starts but it doesn't. What is wrong here ?
-(void)loadView
{
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:YES];
if([NSDate timeIntervalSinceReferenceDate] - startTime >= 5) {
[timer invalidate];
}
}
-(void)targetMethod:(NSTimer *)timer {
NSLog(#"bla");
}
NSDate's timeIntervalSinceReferenceDate is, by default, returning January 1st, 2001. Subtracting the same values will always be 0.
Apple's documentation:
https://developer.apple.com/library/mac/ipad/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html
Here's an idea:
In your .h
#interface MyClass : NSObject
#property (nonatomic, retain) NSTimer *timer;
- (void)targetMethod:(NSTimer *)timer;
- (void)cancelTimer;
#end
In your .m
#implementation MyClass
#synthesize timer;
-(void)loadView
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:YES];
[self performSelector:#selector(cancelTimer) withObject:nil afterDelay:5.0];
}
-(void)cancelTimer {
[self.timer invalidate];
}
-(void)targetMethod:(NSTimer *)timer {
NSLog(#"bla");
}
This is short and simple:
NSDate *endtime = [NSDate dateWithTimeIntervalSinceNow:5];
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(timerTick:)
userInfo:endtime
repeats:YES];
-(void)timerTick:(NSTimer*)timer
{
NSLog(#"timer tick");
if ( [timer.userInfo timeIntervalSinceNow] < 0 )
{
[timer invalidate];
NSLog(#"invalidating timer");
}
}
Your time difference is always 0 so you never invalidate it!
Try setting startTime before you set the timer.
You get the 'startTime' value and the value you compare it to are identical. Your calculation will always give 0. You must store the 'startTime' in your loadView method and then use it in the calculation.