Stop watch and timer - ios

I want to use NSDate and NSTimer to retrieve the elapsed time between I press a start button and a stop button and present the time in seconds. Then I want to use the time for a calculation. I know how to get the time but it is always in format like this 2013-01-15 14:01:55.369.
How do I subtract one time from the other to get the seconds.
I am not sure how to use NDDate and NSTimer.
This should be really easy but I am sort of stuck here.

//Make two properties `NSDate *startDate, *endDate`
//in the action method of start Button
startDate=[NSDate date];
//in the action method of stop Button
stopDate=[NSDate date];
long elapsedSeconds=[stopDate timeIntervalSinceDate:startDate];
NSLog(#"Elaped seconds:%ld seconds",elapsedSeconds);
Please check my project for stopwatch kind of thing, this may come handy for you
Check this code, most of requirement are solved here.

You can use
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)date
to get the time interval between the receiver and a given date in seconds.

To get current time from NSData use:
[[NSData data] timeIntervalSince1970];
and just substract it from your NSTime value.

Use timeIntervalSinceDate between the start date and en stop date.

Related

Call method on second - iOS

I have a method which displays a clock with seconds and the current time. This works fine except that this code will get called either half way through the current second or three quarters of the way through the current second depending on what time I open the app or run it. The method is called through the viewDidLoad method. When this happens my clock will be off up to almost 1 second. Is there any way to start my method when the next second start exactly? i.e. start it when the devices time is HH:MM:SS.000? Note: sorry if this is confusing with the excessive use of second and clock. I just mean I need to start my method at HH:MM:SS.000 (devices internal clock)
Using:
- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)seconds
target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo
repeats:(BOOL)repeats
With an object of NSTimer is probably the way to go.
Add the logic found in this StackOverflow question/answers and you should be able to get it right on an exact second. (Use the logic there to create an NSDate object with resolution to 1 second, then use that date in the method I mentioned above).
NSTimer *yourTimer = [[NSTimer alloc] initWithFireDate:nowToTheSecond
interval:1.0 target:self selector:#selector(updateClock) userInfo:nil
repeats:YES];
[[NSRunLoop mainLoop] addTimer:yourTimer forMode:NSRunLoopCommonModes];
NSTimer objects are not exact. They depend on the app visiting the event loop frequently, and can vary by 50 MS or more (according to what I've read in the docs). If I remember correctly they try to "snap back" to the desired time interval rather than drifting, but any given firing will not be exact.
That said, I guess what I would do is to take the current NSDate, convert it to an NSTimeInterval, take the ceiling value (the next higher whole number) and start a one-time timer that will fire at that moment. Then in the handler for that timer, start a once-a-second timer. Something like this:
//Get the current date in seconds since there reference date.
NSTimeInterval nowInterval =[NSDate timeInervalSinceReferenceDate];
//Figure out the next even second time interval.
NSTimeInterval nextWholeSecond = ceil(nowInterval);
//Figure out the fractional time between now and the next even second
NSTimeInterval fractionUntilNextSecond = nextWholeSecond - nowInterval;
//Start a one-time timer that will go off at the next whole second.
NSTimer oneTimeTimer = [NSTimer timerWithTimeInterval: fractionUntilNextSecond
target: self
#selector: (startSecondTimer:)
userInfo: nil
repeats: NO];
And the startSecondTimer method:
- (void) startSecondTimer: (NSTimer *)timer;
{
//Start a new, repeating timer that fires once per second, on the second.
self.secondsTimer = [NSTimer timerWithTimeInterval: 1.0
target: self
#selector: (handleSecondTimer:)
userInfo: nil
repeats: YES];
}
You should still calculate the new time in each call to your handleSecondTimer: method rather than relying on the number of times you are called, because if the system gets really busy at the moment when it's supposed to call your timer and can't get to you, it might skip a call completely.
Disclaimer: I haven't tried this, but it should work. My only concern is edge cases. For example, when the next whole second is too close to now and the one-time timer can't fire fast enough. It might be safer to add a second to the fractionUntilNextSecond value, so the second hand doesn't start running for greeter than 1 second but less than 2 seconds.

How can I know application startup time?

How can I find out what time the application was launched (Since the beginning of the show Splash Screen.)?
If we use:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
NSDate *date = [NSDate date];
In this case time spent on showing Splash screen is not considered.
Tried to use:
NSDate *startTime = [NSDate dateWithTimeIntervalSinceNow:clock()/CLOCKS_PER_SEC];
But it returns an incorrect value.
Any idea how I can find the correct value?
Register the start time either in your app main function or in the application delegate init method.
Then in application:didFinishLaunchingWithOptions take current time and subtract them.
You can use Instruments (from Xcode - Product -> Profile or CMD+I). You can use the Time Profiler there. The description of the Time Profiler: Performs low-overhead time-based sampling of processes running on the system's CPUs. Plus you can see a timeframe with any template.
If you have to do it in your code, you can use #Sulthan suggestion.
In Time Profiler, Expand the call tree (Main Thread -> start -> main -> … -> [appdelegate application:didFinishLaunchingWithOptions:]). In the Running Time column you will find the time taken info.

Have the current server time locally in the app.

I'm building an app that is using a lot of NSDate class. But NSDate uses the time from the device, so if the user changes the hour in it's device the app is going to have a fake time/date and the app is not going to be synced with the server and the user experience is going to be bad...
So I need somehow to get all the dates relative to the server, I can request the time to the server each time I do a [[NSDate alloc] init]because I'm using that A LOT... so I need a way to always get the date relative to the server... something like [[MYDate alloc] init] and having my server time there...
The best solution I could think off so far is: When the app starts I ask the server it's current unix time, after having that response I set inside a singleton a selector running once per second updating this unix time and I change every call to [[NSDate alloc] init] with my own Singleton class that keeps my server time updated... What I'm not sure how to handle is when the app goes to background... my time is not going to be synced...
What do you guys think about this??
Thanks!!
This can be easily accomplished by using an NSDate subclass.
e.g.
#interface MyDate : NSDate{
}
#end
#implementation MyDate
- (id) init{
if(![super initWithTimeIntervalSince1970:[ServerSingleton time]])
return nil;
return self;
}
#end
That should do what you are asking. As for the singleton, you don't need to check every second, that is a lot of work for the iOS device, the network, and your server. Instead, you only need to check the server once, at the start of your app. Then, have your singleton look something like this:
- (void)checkTime{
self.timeOffset = serverTime - deviceTime;
}
- (time_t)time{
return deviceTime - self.timeOffset;
}
That should only require checking once, to get the current difference in time between the device and the server. Then, you just subtract the time offset from the current device time to get the current time on the server.

Find out when a repeating UILocalNotification was fired

I have a UILocalNotification that is set to start at 2012-06-18 10:00 with a repeat interval of 1 minute.
At 2012-06-18 10:05 5 notifications would have been triggered. The user would then choose notification number 3. The notification should have been fired at 2012-06-18 10:02.
In my - application:didReceiveLocalNotification: method. How can I programatically get this fire date from notification number 3 which should be 2012-06-18 10:02. I know I can get the intitial/start fireDate property from the UILocalNotification but I'm not interested in that. I'm interested to know the fireDate of this repeating notification (not the intial/start fireDate).
If someone can explain to me how to find out which repeating UILocalNotification was fired without parsing the - description of the notification I will give you some of my hard earned bounty.
So I have given this a bit more thought, and as I said in my comment it doesnt seem possible because of the way notifications are handled.
You create one and fire immediately or schedule it.
A notification is just the storage of some information which means it is only meant to be read for its properties.
The application receives the notification through
application:didReceiveLocalNotification:
In where only the UILocalNotification itself is passed. This notification ONLY has a bunch of properties which were set at the start.
The repeat interval is only used to re-notify the user, it doesnt change what the notification has inside.
This comes to the conclusion that for the behavior you expect to achieve you would have to fire different notifications if you expect to pass different information or perform different actions.
(Sub-classing is also not useful as explained here https://stackoverflow.com/a/8583329/1068522)
The best alternate solution to getting the fireDate of the UILocalNotification is to calculate the date.
Given that you have an initial fireDate, you can use the repeated interval to calculate the fireDate of a given notification.
1.Start with the initial fire date
2.Get the notification number/index of the notification you have
3.Multiply the repeated interval by the index and add it onto your initial fire date
However, date calculating, as mentioned in the below link, is tricky due to time zones and "other nasty things."
Here's a helpful link:
How to grab the NEXT fire date from a UILocalNotification object
And of course, there is the final, fall back solution of parsing the description method. Using [notification.fireDate description] However, as you probably know, it is NEVER a good idea to do so because the formatting may change in the future, thus breaking your code.
Hope this helped!
Edit:
Example: Okay, so say my first initial fireDate was 2012-06-18 10:00
I know that my repeated interval is every ONE minute, right?
So say, that the user taps uilocalnotification number 3, then that means TWO minutes should have passed!
THEREFORE, the time for that specific notification is: 2012-06-18 10:02
Does this make sense?
Q:
If someone can explain to me how to find out which repeating
UILocalNotification was fired without parsing the - description of the
notification I will give you some of my hard earned bounty.
A: The easiest way:
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSDateComponents *comps = [[NSCalendar currentCalendar] components:notification.repeatInterval fromDate:notification.fireDate toDate:[NSDate date] options:0];
NSLog(#"Notification #%d", [comps minute] + 1);
}
Q: How to get that "next fire date" from description without parsing?
A: There is private/undocumented function for this: nextFireDateForLastFireDate
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"next: %#", [notification nextFireDateForLastFireDate:[NSDate date]]);
}
Q: Maybe there is some kind of count in notifications? property or method?
A: There's undocumented properties:
#property (assign, nonatomic) int totalRepeatCount;
#property (assign, nonatomic) int remainingRepeatCount;
But they seem to have always same value: UILocalNotificationInfiniteRepeatCount. Both of them is managed by operating system, so overwriting of this properties or underlying instance variable does nothing. Moreover, nothing changes inside UILocalNotifications from firing to firing, there's no way to distinguish one UILocalNotification from another (except address in memory). Next fireDate is calculated basing on current time.

mpmovieplayercontroller stop function, and then play with current time (iPhone)

I have this situation:
Play (streamed) video, stop by code the video, and then play again.
The problem is that the video is begin from the start and not when i stopped it.
What solution do you now of?
EDIT: As #willcodejavaforfood has pointed out, stop only pauses the movie - calling play should restart where you left off so you shouldn't ever need my answer! Can you post the code you are using so we can see what's going on? Thanks.
If you want it to restart where you left off, you will need to remember how far through the movie you were and set the initialPlaybackTime property before you call play again.
i.e. Store the time when you start the movie
...
[myMoviePlayer start];
startDate = [[NSDate date] retain];
...
Store the time you stop the movie
...
[myMoviePlayer stop];
endDate= [[NSDate date] retain];
...
And when you start playback again, use the difference between these times
...
[myMoviePlayer setInitialPlaybackTime:[endDate timeIntervalSinceDate:startDate]];
[myMoviePlayer play];
...
Sam
PS To force it to start at the start, just set the initial playback time to 0.0
PPS I don't know how accurate NSDate is in milliseconds so you might have to use a better way of working out the current position in the movie :)

Resources