2012-02-10 84 views
11

目前我有一个闹钟(本地通知)的计时器。如何从自定义类创建和取消唯一的UILocalNotification?

我想从这段代码创建一个计时器类来创建多个计时器和通知(最多5个),我正在努力如何使用类方法创建和取消唯一通知。

- (UILocalNotification *) startAlarm { 

    [self cancelAlarm]; //clear any previous alarms 

    alarm = [[UILocalNotification alloc] init]; 
    alarm.alertBody = @"alert msg" 
    alarm.fireDate = [NSDate dateWithTimeInterval: alarmDuration sinceDate: startTime]; 
    alarm.soundName = UILocalNotificationDefaultSoundName; 

    [[UIApplication sharedApplication] scheduleLocalNotification:alarm]; 

} 

我的假设是,如果我有一个创建一个名为UILocalNotification类方法“报警”的iOS会看到所有的通知为相同的通知和下面的方法将无法正常工作我希望它的方式:

- (void)cancelAlarm { 

    if (alarm) {  
     [[UIApplication sharedApplication] cancelLocalNotification:alarm]; 
    } 

} 

所以我需要一种方法来命名这些UILocalNotifications,因为它们被创建,例如alarm1 alarm2 ... alarm5,所以我可以取消正确的一个。

在此先感谢。

+0

您可以将它们存储在NSMutableArray或NSMutableDictionary(为其分配键)并通过遍历容器释放它们。 – 2012-02-11 00:45:06

+0

谢谢,我会试试看。 – 2012-02-12 00:33:12

回答

32

您问题的答案在于userInfo字典参数,每个UILocalNotification都有。您可以为此字典中的键设置值以标识通知。

要实现这一点很容易,所有你需要做的就是让你的定时器类具有NSString“name”属性。并使用一些类宽字符串作为该值的关键字。这里有一个基于你的代码的基本例子:

#define kTimerNameKey @"kTimerNameKey" 

-(void)cancelAlarm{ 
    for (UILocalNotification *notification in [[[UIApplication sharedApplication] scheduledLocalNotifications] copy]){ 
     NSDictionary *userInfo = notification.userInfo; 
     if ([self.name isEqualToString:[userInfo objectForKey:kTimerNameKey]]){ 
      [[UIApplication sharedApplication] cancelLocalNotification:notification]; 
     } 
    } 
} 
-(void)scheduleAlarm{ 
    [self cancelAlarm]; //clear any previous alarms 
    UILocalNotification *alarm = [[UILocalNotification alloc] init]; 
    alarm.alertBody = @"alert msg"; 
    alarm.fireDate = [NSDate dateWithTimeInterval:alarmDuration sinceDate:startTime]; 
    alarm.soundName = UILocalNotificationDefaultSoundName; 
    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.name forKey:kTimerNameKey]; 
    alarm.userInfo = userInfo; 
    [[UIApplication sharedApplication] scheduleLocalNotification:alarm]; 
} 

这个实现应该是相对自我解释的。基本上,当计时器类的实例调用-scheduleAlarm并且它正在创建新通知时,它将其字符串属性“name”设置为kTimerNameKey的值。所以当这个实例调用-cancelAlarm时,它枚举了一个通知数组,查找一个通知,该通知的名称是该密钥的名称。如果它找到一个它删除它。

我想你的下一个问题将是如何给你的每个定时器名称属性一个唯一的字符串。

self.timerA.name = @"timerA"; 
self.timerB.name = @"timerB"; 

你也可以用一个标题标签配合name属性:因为我碰巧知道你正在使用IB来实例化它们(从你对此事的另一个问题),你可能会在viewDidLoad像这样做你可能有。

+0

非常感谢!非常清楚的解释,以及一个可靠的代码示例。一切都很有意义,它像一种魅力。然而,我很好奇的一件事是为什么有必要复制cheduledNotifications。 – 2012-02-17 05:28:23

+1

@jemicha很高兴能帮到你。要回答你为什么需要复制'scheduledLocalNotifications'的问题,事实并非如此。这是我极端偏执的一个例子。如果苹果公开了它的通知的内部'NSMutableArray',无论是通过策略更改(不太可能是可笑)或一个错误,那么这个副本将避免可能的问题。但是,如果你放弃它,你可能永远不会看到差异。 – NJones 2012-02-18 18:35:45

+0

你把'''dictionaryWithObject:self.name'''放在哪里 - 你如何改变'''self.name'''为一个唯一的ID? – Supertecnoboff 2016-03-20 11:03:08