简体   繁体   中英

How to get the right date from UIDatePicker for Local Notification

- (IBAction)addReminder:(id)sender {
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSDate *date = [self.datePicker date];
    //break date up:
    NSDateComponents *dateComps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    NSDateComponents *timeComps = [calendar components:NSCalendarUnitHour |NSCalendarUnitMinute |NSCalendarUnitSecond fromDate:date];
    //set the fire time:
    NSDateComponents *notificationDayComps = [[NSDateComponents alloc] init];
    [notificationDayComps setDay:[dateComps day]];
    [notificationDayComps setMonth:[dateComps month]];
    [notificationDayComps setYear:[dateComps year]];
    [notificationDayComps setHour:[timeComps hour]];
    [notificationDayComps setMinute:[timeComps minute]];
    [notificationDayComps setSecond:[timeComps second]];
    NSDate *notificationDate = [calendar dateFromComponents:notificationDayComps];
    NSLog(@"Setting a reminder for %@", notificationDate);
    UILocalNotification *note = [[UILocalNotification alloc] init];
    if (note == nil) return;
    note.alertBody = @"Hypnotize me!";
    note.fireDate = notificationDate;
    note.timeZone = [NSTimeZone defaultTimeZone];
    //schedule the notification:
    [[UIApplication sharedApplication] scheduleLocalNotification:note];
}

Here is my code. I am reading from the Big Nerd Ranch book. Originally they told me to do this:

- (IBAction)addReminder:(id)sender {
    NSDate *date = self.datePicker.date;
    NSLog(@"Setting a reminder for %@", date);
}

When I hit the button that triggers the code on both methods the date that is logged is not the same date. If I log it with current locale it prints the right date, but when I test it on an iphone it does not use the right date for the reminder. I tried to add the calendar components above and tried many other tips from here and other sites but cannot get it to log the right date or set the right date for a local notification.

2015-11-09 12:42:55.415 HypnoNerd[1251:83127] Setting a reminder for 2015-11-09 20:43:00 +0000

This is what shows up when I choose 12:42 today on the date picker, but clearly it logs the wrong date. I know NSDate is not the same as a typical calendar date, but I still cannot figure out how to make this work so any insight would be wonderful. Thanks

- (IBAction)addReminder:(id)sender {
    self.datePicker.timeZone = [NSTimeZone defaultTimeZone];
    NSDate *date = [self.datePicker date];
    UILocalNotification *note = [[UILocalNotification alloc] init];
    note.alertBody = @"Hypnotize me!";
    note.fireDate = date;
    note.timeZone = [NSTimeZone defaultTimeZone];
    //schedule the notification:
    UIApplication *app = [UIApplication sharedApplication];
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil];
    [app registerUserNotificationSettings:settings];
    [app scheduleLocalNotification:note];
}

This works, but I do not really understand what is going on. If anyone could explain this process in a more general sense I would appreciate it. Thanks for the help.

You need to convert your datepicker date into localtimezone.

Default it has UTC timeZone.Use Below code to get current Date.

NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
[userFormatter setTimeZone:[NSTimeZone localTimeZone]];
[userFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *dateConverted = [userFormatter stringFromDate:self.Datepick.date];
NSLog(@"%@",dateConverted);

"These aren't the droids you are looking for."

I believe the OP's issue was the fact that local notifications were not being triggered and the incorrect conclusion was that this had something to do with time zone settings. The internal time is reported back in GMT (aka "UTC"). We can see this in the posted log message:

 2015-11-09 20:43:00 +0000

Where the +0000 is the indicator that the time has not been shifted either + or - from GMT. There is no need for this time to be reported as local time. In fact, there is no need to mess around with any of the .timeZone properties.

The problem, which is solved in the followup post from @crypt3c is related to the following calls:

 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil]
 [app registerUserNotificationSettings:settings];

As of iOS 8, it is required that a user grants permission to an app to receive one or more notification types; without having granted permission, notifications will fail.

Therefore the correct code for iOS 8 and higher is:

- (IBAction)addReminder:(id)sender {
     NSDate *date = [self.datePicker date];
     UILocalNotification *note = [[UILocalNotification alloc] init];
     note.alertBody = @"Hypnotize me!";
     note.fireDate = date;
     //schedule the notification:
     UIApplication *app = [UIApplication sharedApplication];
     UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil];
     [app registerUserNotificationSettings:settings];
     [app scheduleLocalNotification:note];
 }

There are four UIUserNotificationTypes defined:

UIUserNotificationTypeNone
UIUserNotificationTypeBadge
UIUserNotificationTypeSound
UIUserNotificationTypeAlert

More information on this topic is available in the UIUserNotificationSettings Class Reference from the iOS Developer Library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM