I need to create a Timer that counts down from a string I get from the server. the string outputs total seconds left.
I am using this code – it calculates the initial number time right and it counts down but the minutes are the problem.
EDIT – Every real minute the minute calculation goes up by one. But I don’t understand why it is doing this.
-(void)showTimmer:(id) sender {
//get total amount of seconds
NSString *timeRaw = [ArrayFromServer objectAtIndex:1];
NSArray *timeArr = [timeRaw componentsSeparatedByString:@","];
timetoInt = [timeArr objectAtIndex:0];
int time1 = [timetoInt intValue];
//set the second countdown
NSDate* now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSSecondCalendarUnit) fromDate:now];
NSInteger seconds = time1 - [dateComponents second];
[gregorian release];
// do the hours days maths
int hour = (seconds / 3600 );
seconds -= hour * 3600;
int minute = (seconds / 60 );
seconds -= minute * 60;
int second = seconds;
//set the labels
countdownLabel.text = [NSString stringWithFormat:@"%02dH %02dM %02ds", hour, minute, second];
You’re using your pliers to drive a screw. The
secondsmethod of anNSDateComponentsgives you what you would see on a clock if you looked at the second hand at the time represented by yourNSDate. For example, as I type this, it’s UTC Saturday March 26, 2011, 02:52:04. If I got[NSDate date], turned it into anNSDateComponentsand asked that for itsseconds, I’d get “4”. If I did it again in a second, I’d get “5”, and when the minute clicked over, I’d get “59”, then “0”.You can verify this for yourself; put this in your timer method:
So every time the minute of the actual clock ticks over, your calculation of the remaining time:
subtracts
0fromtime1and gives you backtime1. That’s why you’re having the problem.The way* to fix it is to dump the calendar stuff and use
CFAbsoluteTimeGetCurrent(). First, put the start time in your timer’s userInfo (or in an ivar if you prefer):Then change your calculation of the remaining time (the variable you call
seconds:*: Well, one way, but I think probably the best.