Search code examples
iosobjective-cuidatepickernstimeinterval

NSTimeInterval not always firing


I'm working on a simple radio alarm clock app for a non-mainstream stream I'd like to wake up to. It uses the opting out of background trick to stay running when the phone is locked, similar to Rise/Sleepcycle.

Originally the alarm wouldn't fire the next day if I was to set the alarm before midnight but would always fire pretty much on the turn of the minute if set ahead of the current time but before 00:00

So I've made some adjustments so that the date is also checked. I also included conditions so that it's impossible to set a time before the current time. Now while this takes care of the next day issue, I'm finding the fire itself is temperamental. Sometimes it works perfectly, sometimes there is a huge delay (up to 10 minutes in cases) sometimes it never fires at all. I really cannot figure out for the life of me why this happens.

Below is my code. Does anyone have any ideas as to why it's not consistent?

- (void)viewDidLoad {
    [super viewDidLoad];

radio = [[Radio alloc] initWithUserAgent:@"my app"];
 [radio connect:STREAM_URL withDelegate:self withGain:(1.0)];


 //   dateTimePicker.date = [NSDate date];

    dateTimePicker.date =
    [[ NSDate alloc ] initWithTimeIntervalSinceNow: (NSTimeInterval) 2];
    dateTimePicker.minimumDate =
   [[ NSDate alloc ] initWithTimeIntervalSinceNow: (NSTimeInterval) 0 ];


}


-(void) presentMessage:(NSString *)message {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Radio Alarm" message: message delegate:nil cancelButtonTitle:@"Ok"     otherButtonTitles: nil];
    [alert show];
    }


- (IBAction)alarmSetButtonTapped:(id)sender {

    NSLog( @"Alarm Set Button Tapped");
    NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
    dateFormatter.timeStyle = NSDateFormatterShortStyle;
    dateFormatter.dateStyle = NSDateFormatterShortStyle;

    NSString * dateTimeString = [dateFormatter stringFromDate: dateTimePicker.date];
    NSLog( @"Alarm Set Button Tapped : %@", dateTimeString);

    [self presentMessage:[NSString stringWithFormat:@"Alarm set for %@", dateTimeString]];


NSDate *alarmFireDate = dateTimePicker.date;
NSTimeInterval differenceFromNow = [alarmFireDate timeIntervalSinceNow];
//[alarmFireDate performSelector:@selector(PlayAlarm:) withObject:nil afterDelay:differenceFromNow];
[self performSelector:@selector(PlayAlarm:)
           withObject:(self)
           afterDelay:(differenceFromNow)];

Solution

  • you can use

    [NSTimer scheduledTimerWithTimeInterval:differenceFromNow
        target:self
        selector:@selector(PlayAlarm:)
        userInfo:nil
        repeats:NO];
    

    This timer is quite accurate. If you need to abort the timer, just save the returned NSTimer* from this in a property and call

    [myTimer invalidate];