Only trigger selector from applicationSignifigantTimeChangeNotification at midnight - objective-c

I added an observer in my main view controller to get called when applicationsignifiganttimechange gets triggered, but I only want that to happen at midnight. By nature, applicationsignifiganttimechange happens when time format changes, and time zones changes, Etc. I need to know how I can focus it down to only at midnight.
Any thoughts?
Thanks.

Related

How would you go about implementing a "dayDidChange" method, while avoiding the use of NSTimer?

How would you go about implementing a "dayDidChange" method?
I have a dateLabel, that needs updating, when the day changes.
I already had 2 solutions implemented. But gave up on them.
1st, on viewWillAppear, I would set my label. Chances for date changing when the user is viewing the VC are VERY small ... and it wouldn't really introduce any "errors" to execution But still, it's not perfect.
2nd, I also implemented an NSTimer with intervals of 1 second. Works great. But I'm not too found of the idea of having a method being called if there is a chance that I don't need to do it.
Are there any other options? I need to update that label, when the day changes. Also, is it possible to use NSNotificationCenter with this?
In your appliciation delegate, implement the following method: -(void)applicationSignificantTimeChange:(UIApplication *)application
This method is called when the day changes, or if the device's time has been changed in the background for whatever reason (such as changes to time zone).
hope it helps. happy coding :)
You can calculate the time left on the day and set a timer to it. You can also listen to UIApplicationSignificantTimeChangeNotification. Note that this notification will be fired not only when the date changes, but for timezone adjustments and other changes. Keep in mind also that the firing of the notification will be triggered only if your app is not in an inactive state.
There are many ways to do so, and I can elaborate more on them if needed.
But here is a nice quick trick
use this code in your app delegate
it will listen to time changes (when the date or time changes dramatically) and when that happens - run a test and update the label if needed.
read me about this here: https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html
It's just a quick simple way of doing it without timers.
- (void)applicationSignificantTimeChange:(UIApplication *)application {
NSLog(#"Time has changed, do a test and update the label if needed");
// [yourViewController runTimeTestAndUpdateFunction];
}

Timer that works in the background

For the sake of learning i'm making a timer. Used an NSTimer but it appears this stops
when going to the background.
Thought of using NSDate instead. Does this work in the background?
Do i compare current time to a set time to get the timer running properly?
Some thoughts would be greatly appreciated!
If you are looking for something to handle time based events in the background, have a look at UILocalNotification. With a local notification, the OS will alert the user at the appointed time whether the app that scheduled the notification is running or not.
If you are looking for something to happen when the app starts, you can use NSUserDefaults and store a value containing the current timestamp. Fire this off when in the AppDelegate inside applicationWillResignActive method. You can then check this value in the applicationDidBecomeActive.

How can I change a label with a date once the system date changes in iOS?

I have a simple query but don't know how to do it.
This is what I am trying to achieve:
1) I have a UILabel with todays date i.e. "29/04/12"
2) At midnight I want that label to update by itself to "30/04/12" without needing to change view or press anything.
It's step 2 that I don't know how to do. I have idea's of how it would be done such as potentially getting a system notification of the date change (if this is even possible) or using some sort of timer as a trigger.
Any help would be greatly appreciated, thanks in advance.
If you are only interested in being notified when midnight arrives (or a couple other cases), then you can override UIApplicationDelegate's - (void)applicationSignificantTimeChange:(UIApplication *)application method so that it causes your labels to update. Of course, you'll also want to update the labels whenever the application re-enters the foreground, since this method won't be called if your app is in the background when the date changes.

How to display time in seconds in Cocoa efficiently?

I want to display the time (including seconds) in an application in a text field, pretty simple. What I currently do is create a NSTimer that runs every 0.1 seconds that gets the system time and updates the text field. This seems like a terribly inefficient way to accomplish this. Is there a better way?
Are you displaying it to tenth-of-a-second (or finer) resolution?
If so, I see no problem. Usually, polling sucks because what you're checking might not have changed, but it's not like time is going to stop on you. So a tenth-of-a-second timer is fine.
If not, create a timer whose interval is the desired resolution, then get its fire date, round it down to the desired resolution (e.g., a whole second if you update every second), and set that as the new fire date. Then, your timer will only fire coincidentally with the times it's appropriate to update your clock view.
Note that while time always moves, it doesn't always move linearly: it may jump ahead or backward by an hour or half an hour, or any amount if the user (or ntpd) changes the system clock setting. On Mac OS X 10.6 and later, you can observe for the NSSystemClockDidChangeNotification, and re-adjust your timer's fire date when that happens.
How about you use NSTimer that runs every second and then you check the firing time and make sure it is exactly on the start of a second. You can use initWithFireDate:interval:target:selector:userInfo:repeats: or set the next invocation time appropriately using setFireDate: after the timer was created:
NSTimeInterval interval = [[timer fireDate] timeIntervalSinceReferenceDate];
NSTimeInterval nextFire = ceil(interval);
[timer setFireDate: [NSDate dateWithTimeIntervalSinceReferenceDate: nextFire];
Then you'll be sure that the timer fires as close to the needed time as possible and don't worry about the timer lagging behind because it resets itself after each firing using intended firing date and interval you provided, so it will always try to fire at exact second (but will fire whenever the run loop will be able to do that).
I'm not sure what else would be more efficient. As long as the callback for your timer is not doing anything too intensive, you're probably close to optimal.
How about using gettimeofday(2)? It returns much exact time information to use.

Can you Bind to the timeInterval attribute of an NSDatePicker?

I've got a Core Data application that has an Event class, which has a start date and a finish date. It's trivial to bind these to a pair of NSDatePicker widgets, but I wanted to make it work with the NSRangeDateMode available in Leopard.
The NSDatePicker has a pair of methods that deal with timeInterval, but I don't seem to be able to bind to this.
Update: I've used a manual call to do the binding, and it half works:
[picker bind:#"timeInterval"
toObject:array
withKeyPath:#"selection.timeInterval"
options:options];
It sets the timeInterval in the NSDatePicker when the underlying object is changed, but does not set the underlying object when the NSDatePicker's timeInterval is changed.
Sadly, no. The timeInterval property of the date picker is not even properly key-value observable. Basically, you're stuck either setting up an action method or using the delegate validation method to receive updates to its value. Also, you'll want to round it off to the nearest multiple of 86400.0 (i.e. the number of seconds in a day), since the date picker is consistently off by some fraction of a second in its reported timeInterval. Perhaps by the time Snow Leopard rolls around, this feature will be fully baked.
The interval support is only available when you're using the graphical version of the date picker. Even then, there's no native binding support for timeInterval.
Also depending on how you're intending to use this the UI to select ranges that extend past the current month is poor in my opinion.
1169097 explains how to implement custom bindings.