Задержка при вызове UILocalNotification

Я сделал приложение, которое является настраиваемым сигнальным приложением. UILocalNotification должна вызывать в момент, выбранный мной в UIDatePicker, но не вызывается при правильном времени. Например, я выбрал время как 2:00 PM для тревоги, поэтому уведомление будет вызываться между 2:00 PM и 2:01 PM... но не уверен, когда... это дает мне задержку случайного времени. В моем UITableView вы можете видеть, что это описание отображается также ошибочно. Я знаю, что я из Индии, поэтому он показывает время по Гринвичу, но можно ли его исправить?

Вот мой весь код: - -----------------------------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];
}

- (********) 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");
 }
}

На этом рисунке показано мое приложение:

3 ответа

Я думаю, что проблема здесь связана с тем, что 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 с нулевыми секундами для вашего сигнала тревоги. Вы должны получать гораздо более точную точность от своих уведомлений, но я не думаю, что они гарантированно будут на долю секунды.


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;


просто имейте в виду, дата с datepicker совпадает с GMT. вам нужно самостоятельно преобразовать свой часовой пояс. это может быть проблемой в вашем случае.

licensed under cc by-sa 3.0 with attribution.