我的Mac应用程序中有一些代码可以执行长时间的导出操作。在导出结束时,它将创建一个用户通知,以让用户知道它已完成:
- (NSUserNotification*)deliverNotificationWithSound:(NSString*)sound title:(NSString*)title messageFormat:(NSString*)message {
NSUserNotification * note = [NSUserNotification new];
note.soundName = sound;
note.title = title;
note.informativeText = [NSString stringWithFormat:message, NSRunningApplication.currentApplication.localizedName, self.document.displayName];
note.userInfo = @{ @"documentFileURL": self.document.fileURL.absoluteString };
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:note];
return note;
}
然后,它放一张表格,其中包含有关导出的详细信息(遇到警告,方便的“显示”按钮等)。当他们解雇工作表时,我想删除通知,如下所示:
[NSUserNotificationCenter.defaultUserNotificationCenter removeDeliveredNotification:note];
但是,这实际上并未从通知中心删除通知。我设置了一个断点;运行
-removeDeliveredNotification:
行,并且note
不为nil。是什么赋予了? 最佳答案
您尝试删除的通知必须位于deliveredNotifications
数组中。引用-removeDeliveredNotification:
的文档
如果用户通知不在deliveryNotifications中,则什么都不会发生。
调用-deliverNotification:
时,您的通知可能会被复制,因此保留对该实例的引用并尝试在以后删除它可能会失败。而是将某些内容存储在通知的userInfo
属性中,以便您可以识别它,然后扫描deliveredNotifications
数组以查找要删除的通知。
由布伦特添加
这是我问题中方法的更正版本。我正在使用原始通知的指针值(转换为整数)来标识副本;这不是万无一失的,但可能已经足够了。
- (NSUserNotification*)deliverNotificationWithSound:(NSString*)sound title:(NSString*)title messageFormat:(NSString*)message {
NSUserNotification * note = [NSUserNotification new];
note.soundName = sound;
note.title = title;
note.informativeText = [NSString stringWithFormat:message, NSRunningApplication.currentApplication.localizedName, self.document.displayName];
note.userInfo = @{ @"documentFileURL": self.document.fileURL.absoluteString, @"originalPointer": @((NSUInteger)note) };
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:note];
// NSUserNotificationCenter actually delivers a copy of the notification, not the original.
// If we want to remove the notification later, we'll need that copy.
for(NSUserNotification * deliveredNote in NSUserNotificationCenter.defaultUserNotificationCenter.deliveredNotifications) {
if([deliveredNote.userInfo[@"originalPointer"] isEqualToNumber:note.userInfo[@"originalPointer"]]) {
return deliveredNote;
}
}
return nil;
}