views:

733

answers:

5

Hi, In iPhone SDK 3.0, I would like to register for a notification, which would alert my application when a certain time is reached. Is it possible? Thanks

A: 

You would start by setting an NSTimer to fire at a certain date, and the selector that fires could be whatever you want. No need to use NSNotifications.

pzearfoss
+1  A: 

Set up an NSTimer that runs a selector every 30 seconds (or whatever granularity you need):

 [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];

The -timerFired: selector (method) will run every thirty seconds and check the hour, minute and second components, firing a notification if elements match the desired time:

 - (void) timerFired:(NSNotification *)notification {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSCalendarUnit unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDate *date = [NSDate date];
    NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date];
    NSInteger hour =  [dateComponents hour];
    NSInteger min =   [dateComponents minute];
    NSInteger sec =   [dateComponents second];
    if ((hour == kDesiredHour) && (min == kDesiredMinute) && (sec == kDesiredSecond)) {
       [[NSNotificationCenter defaultCenter] postNotificationName:@"kTimeComponentsWereMatched" object:nil userInfo:nil];
    }
 }

You register to listen for this notification in some other class somewhere:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomething:) name:@"kTimeComponentsWereMatched" object:nil];

Accordingly, you have a method in that same class that does something interesting:

 - (void) doSomething:(NSNotification *)notification {
    // do something interesting here...
 }

You can merge this code if it is all in one class. Or specify the target in the NSTimer to point to the class instance that you want to run the selector in.

Alex Reynolds
+1  A: 

I'm assuming you want this timer to fire, even if the app is closed. You can use a notification for that but you would have to have a server that issued the notification.

Furthermore, the iPhone would pull up an alert asking the user to open the app - but they could chose not to do so.

Kendall Helmstetter Gelner
+1  A: 

Assuming you have a NSDate in the variable date, and want to fire the method dateIsHere: at that date, do this:

NSTimer* timer = [[NSTimer alloc] initWithFireDate:date
                                          interval:0.0f
                                            target:self
                                          selector:@selector(dateIsHere:)
                                          userInfo:nil
                                           repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:timer
                          forMode:NSDefaultRunLoopMode];
[timer release];
PeyloW
Hi PeyloW, I tried your code in the following manner but I got a NSInvalidArgumentException.Can you please tell me what I am doing here incorrectly---This code is inside a different functionNSDate *date = [[NSDate alloc]init]; date =[NSDate date]; NSTimer* timer = [[NSTimer alloc] initWithFireDate:date interval:0.0f target:self selector:@selector(dateIsHere:) userInfo:nil repeats:NO]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];----(void)dateIsHere{ NSLog(@"Date is here");}Thanks
Felix
I found the problem. I must have the dateIsHere funtcion lik dateIsHere:(NSTimer *)timer. I did not included the timer argument.:)
Felix
A: 

You are looking for "Local Notifications", which is being implemented in iOS since version 4.0:

http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008194-CH1-SW1

This should be the correct answer for >=4.0. For earlier versions, there is probably still only the NSNotifications (implementing push is too much of a hassle for most)

Jonny