Very Interesting Variances with Time on Different Devices - iphone

This timmer works great on all my devices (5, Ipad and two 4S) but it doesn't seem to work on the two 3GS I have. For some reason the time runs really slow on the 3s.
Heres a video explaining the problem:
http://youtu.be/4vdusgnIXcs
And heres the code that deals with the time:
- (void)showTime
{
int hours = 0;
int minutes = 0;
int seconds = 0;
int hundredths = 0;
NSArray *timeArray = [NSArray arrayWithObjects:self.hun.text, self.sec.text, self.min.text, self.hr.text, nil];
for (int i = [timeArray count] - 1; i >= 0; i--) {
int timeComponent = [[timeArray objectAtIndex:i] intValue];
switch (i) {
case 3:
hours = timeComponent;
break;
case 2:
minutes = timeComponent;
break;
case 1:
seconds = timeComponent;
break;
case 0:
hundredths = timeComponent;
hundredths++;
score++;
break;
default:
break;
}
}
if (hundredths == 100) {
seconds++;
hundredths = 0;
}
else if (seconds == 60) {
minutes++;
seconds = 0;
}
else if (minutes == 60) {
hours++;
minutes = 0;
}
self.hr.text = [NSString stringWithFormat:#"%.0d", hours];
self.min.text = [NSString stringWithFormat:#"%.2d", minutes];
self.sec.text = [NSString stringWithFormat:#"%.2d", seconds];
self.hun.text = [NSString stringWithFormat:#"%.2d", hundredths];
scoreLabel.text= [NSString stringWithFormat:#"%i",score];
Please help me try to figure out whats going on here. It works so well on the newer devices I'm just lost at what I need to do.
Thank you in advance!

If I understand your code correctly you run a NSTimer 100 times a second.
If that is correct you may primarily have a design problem and not a performance or NSTimer problem.
A NSTimer is not guaranteed to run on time. The only thing that is guaranteed is that it will not run earlier that it is supposed to be.
Since you don't know when a timer method runs you can't rely that it will run exactly 100 times a second. This means a timer is a bad way to "count" time. A better way would be to save the system time when you start the timer, and when you want to know how much time has elapsed you use the current system time and substract the start time. The NSTimer should be used for display purposes only.
Something like this:
// instance variables:
NSDate *startDate;
NSTimer *timer;
- (void)startTimer {
[timer invalidate];
startDate = [NSDate date]; // save current time
timer = [NSTimer timerWithTimeInterval:0.075 target:self selector:#selector(displayTime:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)displayTime:(NSTimer *)timer {
// the timer method is for display only. it doesn't "count" time
// calculate elapsed time from start time
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
NSInteger ti = (NSInteger)elapsedTime;
// convert elapsed time (in seconds) into hours, minutes, seconds ...
double fractionalSeconds = fmod(elapsedTime, 1);
NSInteger hundreds = fractionalSeconds * 100;
NSInteger seconds = ti % 60;
NSInteger minutes = (ti / 60) % 60;
NSInteger hours = (ti / 3600);
NSLog(#"%02d:%02d:%02d.%02d", hours, minutes, seconds, hundreds);
}

Profile your programs with Instruments.app using both devices and compare. Since you have isolated the problem in the demo, the reports it generates should quickly expose the execution time differences. Once you understand the biggest problem area(s), you will know which parts of the program you can change in order to make it run faster. Then compare your updates with the initial runs to see how the speed has improved. Repeat as needed.

Related

Display timer that works out Days, hours, minutes and seconds from a date then increments in real time

I am trying to Display a timer that works out Days, hours, minutes and seconds from a date then increments in real time on a view/page.
What would be the best approach?
you can do like this way:-
- (void)viewWillAppear:(BOOL)animated
{
[self start];
[super viewWillAppear:YES];
}
int currentTime;
- (IBAction)start{
currentTime = 0;
lbl=[[UILabel alloc]init];
//creates and fires timer every second
myTimer = [[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(showTime) userInfo:nil repeats:YES]retain];
}
- (IBAction)stop{
[myTimer invalidate];
myTimer = nil;
}
- (IBAction)reset{
[myTimer invalidate];
lbl.text = #"00:00:00";
}
-(void)showTime{
currentTime++; //= [lbl.text intValue];
//int new = currentTime++;
int secs = currentTime % 60;
int mins = (currentTime / 60) % 60;
int hour = (currentTime / 3600);
int day = currentTime / (60 * 60 * 24);
lbl.text = [NSString stringWithFormat:#"%.2d:%.2d:%.2d:%.2d",day,hour, mins, secs];
NSLog(#"my lable == %#",lbl.text);
NSLog(#"my lable == %#",lbl.text);
}
The best approach is to read the Date and Time Programming Guide to learn about using the NSDate, NSCalendar, and NSDateComponents classes.

UIProgressBar for AvAudioPlayer playing progress

In my app playing audiofile for that i want to show UIProgressBar on the UIToolbar for audiofile playing progress. Anyone can help me how to code for it.
I use a timer to check the current duration, and then update my progress bar every half second, like so:
tmrCounter = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:#selector(updateElapsedTime) userInfo:nil repeats:YES];
-(void)updateElapsedTime{
if (player) {
[prgIndicator setProgress:[player currentTime] / [player duration]];
[lblTime setText:[NSString stringWithFormat:#"%#", [self formatTime:[player currentTime]]]];
}
}
-(NSString*)formatTime:(float)time{
int minutes = time / 60;
int seconds = (int)time % 60;
return [NSString stringWithFormat:#"%#%d:%#%d", minutes / 10 ? [NSString stringWithFormat:#"%d", minutes / 10] : #"", minutes % 10, [NSString stringWithFormat:#"%d", seconds / 10], seconds % 10];
}
Hope this helps!

Create a count up timer with support for hours, mins seconds, split seconds iPhone sdk

Interested in creating a timer to count up for the user.
I was wondering if I'd have to keep track of all the integer variables separately or if I could use date formatter.
I'm currently using a -scheduledTimerfoo to call an -updateLabel method with seconds, but It looks a bit horrible after 100 seconds. I'd sort of like "hours:mins:seconds:split seconds" to display.
Cheers
Sam
NSDateFormatter is only for formatting dates, not intervals of time. A better way to do this would be to record when you start the timer, and every second, update the label with how much time passed since you started the timer.
- (void)startTimer {
// Initialize timer, with the start date as the userInfo
repeatTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateLabel) userInfo:[NSDate date] repeats:YES];
}
- (void)updateLabel:(NSTimer *)timer {
// Get the start date, and the time that has passed since
NSDate *startDate = (NSDate *)[timer userInfo];
NSTimeInterval timePassed = [[NSDate date] timeIntervalSinceDate:startDate];
// Convert interval in seconds to hours, minutes and seconds
int hours = timePassed / (60 * 60);
int minutes = ((int)timePassed % (60 * 60)) / 60;
int seconds = (((int)timePassed % (60 * 60)) % 60);
NSString *time = [NSString stringWithFormat:#"%i:%i:%i", hours, minutes, seconds];
// Update the label with time string
}

how can I make a counter or timer using NSDate or NSCalendar?

I am new to iphone development, I am developing an application, which takes restaurant order data (Name of Restaurant and order price) and save to an array and display on another UITable, but now I want to start a timer such as
Royal Taj
$35
1 hour, 40 mints remaining,
so how can I count such time, on different orders, I need a little guide regarding it, and time should go in decrement, not increment ,,,,
if you are not clear about my question, then u can ask me anything again....
here is what i have done and its working ...........
{
NSDictionary* temp = [allOrder objectAtIndex:indexPath.row];
NSDate* dt = (NSDate*)[temp objectForKey:#"date"];
NSTimeInterval inter = [dt timeIntervalSinceNow];
int hour = inter / 3600;
int min = ((long)inter % 3600)/60;
NSString* str;
if (hour == 0)
{
if (min == 0)
str = [NSString stringWithFormat:#"Order is ready to serve"];
else
str = [NSString stringWithFormat:#"%d minutes remaining",min];
}
else {
if (min == 0)
str = [NSString stringWithFormat:#"%d hours remaining",hour];
else
str = [NSString stringWithFormat:#"%d hours and %d minutes remaining",hour,min];
}
cell.detailTextLabel.text = str;
}
here i supposed that u have an array allOrder which contains dictionaries which has object for keys #"date" as the date on which order has to be delivered.

iPhone: NSTimer Countdown (Display Minutes:Seconds)

I have my timer code set up, and it's all kosher, but I want my label to display "Minutes : seconds" instead of just seconds.
-(void)countDown{
time -= 1;
theTimer.text = [NSString stringWithFormat:#"%i", time];
if(time == 0)
{
[countDownTimer invalidate];
}
}
I've already set "time" to 600, or 10 minutes. However, I want the display to show 10:59, 10:58, etc. until it reaches zero.
How do I do this?
Thanks!
int seconds = time % 60;
int minutes = (time - seconds) / 60;
theTimer.text = [NSString stringWithFormat:#"%d:%.2d", minutes, seconds];
By the time, I was made a little upgrade of first answer, it removed conflicts that associated from NSInteger and int:
NSInteger secondsLeft = 987;
int second = (int)secondsLeft % 60;
int minutes = ((int)secondsLeft - second) / 60;
theTimer.text = [NSString stringWithFormat:#"%02d:%02d", minutes, second]];