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.
Related
My app has a timer which when the app goes in the background pauses.
To still have the right time when the app comes back in the foreground, I set an NSDate called exitDate in the AppDelegate as follows:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
self.exitDate = [[NSDate alloc] init];
}
and an NSDate called reentryDate as follows:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
self.reentryDate = [[NSDate alloc] init];
}
Then I get the difference of both NSDates and add them to my timer.
This all works fine as long as the app is not terminated in the background.
If it does get terminated the App starts from the first viewController and the timer has stopped.
To fix that problem I use state restoration. Which also works fine.
Even if the app gets terminated, the app starts back at the last viewController with everything I saved beforehand.
The only thing that doesn't seem to get saved in state restoration is my exitDate even though I explicitly asked to do so.
When the app comes back, the exitDate always equals nil.
I assume it has something to do with the time the exitDate gets set which probably is after the method as follows is called:
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.exitDate forKey:#"UnsavedExitDateAppDelegate"];
}
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
self.exitDate = [coder decodeObjectForKey:#"UnsavedExitDateAppDelegate"];
}
Problem is I've tried setting exitDate in -applicationWillTerminate, -applicationDidEnterBackground and -applicationWillResignActive but everytime when the app starts back up, exitDate is nil.
Any ideas?
Convert NSDate to NSString using NSDateFormatter and save this String in NSUserDefaults on 'Did Enter Background'
And on WillEnterForeground get this NSString and using same NSDateFormatter syntax convert it to NSDate.
Or you can save in Plist and retrieve it vice versa.
You can save your date or any data in shared preferences. Data would be persistence even if app is closed in background. Will definitely take off lots of pain from you as compared to your current method. Let me know if you need more explanation ..:)
Save the date to NSUserDefaults. Don't forget to call the synchronize method, even though this is supposed to happen automatically when the app is backgrounded, because you might be adding your date to it slightly after this happens.
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.
I noticed that if I set my device time manually, and turn off the automatic time sync on my iOS device, [NSDate date] returns the date and time assuming the device time is correct--which it may not be.
Since the docs mention that NSDate has some sort of sync with NTP, I am wondering if there is any built-in way to get the accurate date and time instead of having to assume the device date and time is correct.
Perhaps https://github.com/jbenet/ios-ntp can help you? It's a library that can fetch the date and time from a time server.
I tried ios-ntp but didn't get expected results, so I found another library which is working fine and really easy to implement.
NHNetworkTime
Pods:
pod 'NHNetworkTime'
pod 'CocoaAsyncSocket'
Simple to use
Import this whenever you want to get time:
#import "NHNetworkTime.h"
Call synchronize in - application: didFinishLaunchingWithOptions: to update time from server when you launch app:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NHNetworkClock sharedNetworkClock] synchronize];
return YES;
}
then you can get network time when sync complete in anywhere in your source code:
NSDate *networkDate = [NSDate networkDate];
or add notification to re-update your UI in anywhere you want when time is updated:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(networkTimeSyncCompleteNotification:) name:kNHNetworkTimeSyncCompleteNotification object:nil];
Cheers !!! :)
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.
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.