UILocalNotification未在正确的时间调用

时间:2011-11-04 10:55:50

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

已编辑:

很抱歉重新编辑问题,但实际上我没有得到答案,我需要什么。我认为我提出问题的方式是错误的,所以重写整个问题:

我已经制作了App,其中是一个自定义报警应用程序。 UILocalNotification应该在我在DatePicker中选择的时间调用,但是没有在正确的时间调用。 例如,我为闹钟选择时间为下午2:00,因此通知将在下午2:00到2:01之间调用...但不确定何时...它给了我一个随机时间的延迟。 在我的TableView中你可以看到它显示的描述也是错误的。我知道我来自印度,所以它显示了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

此方法未调用enter image description here

3 个答案:

答案 0 :(得分:2)

我认为这里的问题与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]; // now you have an NSDate with zero seconds for your alarm

您的通知应该会有更好的准确性,但我认为它们并不能保证完全处于分秒状态。

答案 1 :(得分:1)

这是一个问题:

    NSDate *selectedDate = [[NSDate alloc] init];
    selectedDate = [datePicker date];

你正在泄漏你分配的NSDate,然后扔掉。摆脱alloc / init并将nil分配给指针。但这并不能解释你的大问题。

除此之外,要么是你没有向我们展示的东西,或者你在采样时日期选择器仍在移动。

答案 2 :(得分:1)

如果您只是在NSDate对象上调用description(这是您在cellForRowAtIndexPath方法中执行的操作),您将获得日期的内部表示,即GMT。您需要使用NSDateFormatter将其区域设置设置为设备区域设置,并使用它的stringFromDate:方法获取显示日期。