如何从自定义类创建和取消唯一的 UILocalNotification?

Posted

技术标签:

【中文标题】如何从自定义类创建和取消唯一的 UILocalNotification?【英文标题】:How do I create and cancel unique UILocalNotification from a custom class? 【发布时间】:2012-02-10 17:58:55 【问题描述】:

目前我有一个带闹钟的计时器(本地通知)。

我想从此代码创建一个计时器类以创建多个计时器和通知(最多 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 所以我可以取消正确的。

提前致谢。

【问题讨论】:

您可以将它们存储在 NSMutableArray 或 NSMutableDictionary 中(为它们分配一个键)并通过遍历容器来释放它们。 谢谢,我试试看。 【参考方案1】:

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

要轻松实现这一点,您所要做的就是让您的计时器类具有NSString“名称”属性。并使用一些类范围的字符串作为该值的键。这是基于您的代码的基本示例:

#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 时,它会枚举通知数组以查找具有该键名称的通知。如果它找到一个,它会删除它。

我想您的下一个问题将是如何为您的每个计时器名称属性赋予一个唯一的字符串。由于我碰巧知道您正在使用 IB 来实例化它们(来自您关于此事的其他问题),您可能会在 viewDidLoad 中执行此操作,例如:

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

您还可以将 name 属性与您可能拥有的标题标签联系起来。

【讨论】:

再次感谢!非常清晰的解释和可靠的代码示例。一切都是有道理的,它就像一个魅力。然而,我很好奇的一件事是为什么有必要复制 cheduledNotifications。 @jemicha 很高兴我能帮上忙。要回答您关于为什么需要复制scheduledLocalNotifications 的问题,事实并非如此。这是我极度偏执的一个例子。如果苹果曾经通过策略更改(不太可能是可笑的)或错误公开其内部NSMutableArray 通知,那么此副本将避免可能出现的问题。但同样,如果你把它排除在外,你可能永远看不到任何区别。 您将dictionaryWithObject:self.name 放在哪里 - 如何将self.name 更改为唯一ID?

以上是关于如何从自定义类创建和取消唯一的 UILocalNotification?的主要内容,如果未能解决你的问题,请参考以下文章

如何从自定义类 Person 创建数据集?

如何将 UISlider 从自定义类文件中移动到某个位置

如何从自定义类添加对我的 Web 服务代理的引用

如何从自定义源的请求中获取 Cloudfront 子域?

如何从自定义表格视图单元类中获取对表格视图控制器的引用

从自定义相册中删除图像