延迟UILocalNotification的调用

时间:2011-12-22 11:47:25

标签: iphone objective-c ios cocoa-touch uilocalnotification

我制作了一款定制闹钟应用程序。 UILocalNotification应该在我UIDatePicker选择的时间调用,但是没有在正确的时间调用。例如,我选择时间作为警报的下午2:00,因此通知将在下午2:00到2:01 PM之间调用...但不确定何时...它给了我一个随机时间的延迟。在我的UITableView中你可以看到显示的描述也是错误的。我知道我来自印度,所以它显示了GMT时间,但可以纠正吗?

这是我的整个代码: - ----------------------------- AppDelegate.m文件:---------------- --------------

@synthesize window,viewController,timeViewController;
NSString *kRemindMeNotificationDataKey = @"kRemindMeNotificationDataKey";
#pragma mark -
#pragma mark === Application Delegate Methods ===
#pragma mark -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    int x = [[NSUserDefaults standardUserDefaults] integerForKey:@"Mayank"];
    if( x == 1 )
    {
        timeViewController = [[TimeViewController alloc]initWithNibName:@"TimeViewController" bundle:nil];
        timeViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
        CGRect frame = timeViewController.view.frame;
        frame.origin = CGPointMake(frame.origin.x,frame.origin.y + statusBarFrame.size.height );
        timeViewController.view.frame = frame;
        [self.window addSubview:timeViewController.view];
    }
    else
    {
        [[NSUserDefaults standardUserDefaults]setInteger:1 forKey:@"Mayank"];
        [[NSUserDefaults standardUserDefaults]synchronize]; 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Do you want to set the Default Alarm?" message:@"at 4:20 PM" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok",nil];
        [alert show];
        [alert release];
    }
    sleep(1);
    [self.window makeKeyAndVisible];
    application.applicationIconBadgeNumber = 0;
    // Handle launching from a notification
    UILocalNotification *localNotification =
    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotification) {
        NSString *reminderText = [localNotification.userInfo 
                                  objectForKey:kRemindMeNotificationDataKey];
        [viewController showReminder:reminderText];
    }
    return YES;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(buttonIndex == 0)
    {
        timeViewController = [[TimeViewController alloc]initWithNibName:@"TimeViewController" bundle:nil];
        timeViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
        CGRect frame = timeViewController.view.frame;
        frame.origin = CGPointMake(frame.origin.x,frame.origin.y + statusBarFrame.size.height );
        timeViewController.view.frame = frame;
        [self.window addSubview:timeViewController.view];
    }
    if(buttonIndex == 1)
    {
        viewController = [[SetAlarmViewController alloc]initWithNibName:@"SetAlarmViewController" bundle:nil];
        viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
        CGRect frame = viewController.view.frame;
        frame.origin = CGPointMake(frame.origin.x,frame.origin.y + statusBarFrame.size.height );
        viewController.view.frame = frame;
        [self.window addSubview:viewController.view];       
    }
}
- (void)application:(UIApplication *)application 
didReceiveLocalNotification:(UILocalNotification *)notification {
    NSString *reminderText = [notification.userInfo
                              objectForKey:kRemindMeNotificationDataKey];
    [viewController showReminder:reminderText];
    application.applicationIconBadgeNumber = 0;
}

----------------------------- mainViewController.m文件:------------- -----------------

@implementation SetAlarmViewController
@synthesize datePicker,tableview, eventText,titleBar,setAlarmButton,returnKeyType;


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {

    [super viewDidLoad];

    appDelegate = (The420DudeAppDelegate *)[[UIApplication sharedApplication] delegate];    
    eventText.returnKeyType = UIReturnKeyDone;

//  datePicker.minimumDate = [NSDate date];
    NSDate *now = [NSDate date];
    [datePicker setDate:now animated:YES];
    eventText.delegate = self;
    index = 0;
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:YES];
    [self.tableview reloadData];
}

- (IBAction) scheduleAlarm:(id) sender {
    [eventText resignFirstResponder];

// Get the current date
    NSDate *pickerDate = [self.datePicker date];

    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.fireDate = pickerDate;
//  NSLog(@"%@",localNotif.fireDate);
    localNotif.timeZone = [NSTimeZone defaultTimeZone];
//  NSLog(@"%@",localNotif.timeZone);

    // Notification details
    localNotif.alertBody = [eventText text];

    // Set the action button
    localNotif.alertAction = @"Show me";
    localNotif.repeatInterval = NSDayCalendarUnit;
    localNotif.soundName = @"jet.wav";
    // Specify custom data for the notification
    NSDictionary *userDict = [NSDictionary dictionaryWithObject:eventText.text
                                                         forKey:kRemindMeNotificationDataKey];
    localNotif.userInfo = userDict;

    // Schedule the notification
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];

    [self.tableview reloadData];
    eventText.text = @"";

    viewController = [[TimeViewController alloc] initWithNibName:@"TimeViewController" bundle:nil];
    [self presentModalViewController:viewController animated:YES];
}

#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [[[UIApplication sharedApplication] scheduledLocalNotifications] count];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    index = indexPath.row;
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Warning!!!" 
                                                        message:@"Are you sure you want to Delete???" delegate:self
                                              cancelButtonTitle:@"Cancel"
                                              otherButtonTitles:@"Ok",nil];
    [alertView show];
    [alertView release];

}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
    UILocalNotification *notify = [notificationArray objectAtIndex:index];

    if(buttonIndex == 0)
    {
        // Do Nothing on Tapping Cancel...
    }
    if(buttonIndex ==1)
    {
        if(notify)
            [[UIApplication sharedApplication] cancelLocalNotification:notify];
    }
    [self.tableview reloadData];
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
    // Configure the cell...

    NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
    UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];

    [cell.textLabel setText:notif.alertBody];
    [cell.detailTextLabel setText:[notif.fireDate description]];    
    return cell;
}


- (void)showReminder:(NSString *)text {
    /*
     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Reminder" 
     message:@"hello" delegate:self
     cancelButtonTitle:@"OK"
     otherButtonTitles:nil];
     [alertView show];
     [self.tableview reloadData];
     [alertView release];
     */

    NSString *path = [[NSBundle mainBundle]pathForResource:@"jet" ofType:@"wav"];
    NSURL *url = [NSURL fileURLWithPath:path];

    player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
    player.numberOfLoops = -1;
    [player play];

    UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:nil];
    [actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
    [actionSheet showInView:self.view];
//  [actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
    [actionSheet release];

}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [player stop];
    if(buttonIndex == 0)
    {
        NSLog(@"OK Tapped");
    }
    if(buttonIndex ==  1)
    {
        NSLog(@"Cancel Tapped");
    }
}

此图片显示我的应用视图:

Alarm App View

3 个答案:

答案 0 :(得分:1)

 NSDate *pickerDate = [self.pickerTime date];
// Break the date up into components
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit ) fromDate:pickerDate];
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:pickerDate];
// Set up the fire time
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:[dateComponents day]];
[dateComps setMonth:[dateComponents month]];
[dateComps setYear:[dateComponents year]];
[dateComps setHour:[timeComponents hour]];
[dateComps setMinute:[timeComponents minute]];
**[dateComps setSecond:00];**
NSDate *itemDate = [calendar dateFromComponents:dateComps];
localNotification.fireDate = itemDate;

答案 1 :(得分:0)

请记住,datepicker的日期与GMT一致。你必须自己转换到你自己的时区。这可能是你案件中的问题。

答案 2 :(得分:0)

我认为这里的问题与NSDatePicker有关,它返回当前时间的秒数和所选时间。您需要从NSDatePicker返回的日期中删除秒数,并将其用于警报和本地通知。

NSDate *selectedDate = [datePicker date]; // you don't need to alloc-init the variable first
NSCalendar *cal = [NSCalendar currentCalendar];  
NSDateComponents *dc = [cal components: (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:selectedDate];
selectedDate = [cal dateFromComponents:dc];

//现在你的警报有一个零秒的NSDate 你的通知应该会有更好的准确性,但我认为它们不会保证完全是在瞬间。