2012-02-10 86 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