问题
In our app we are displaying Notification Center notifications in alert style.
Displaying notification works fine, as well as we get callback when user interacts with the notification either by clicking on notification or by clicking on Action button.
However, we are interested in getting a callback or event when user clicks on Other button in notification. I have seen MAC OS does this when it displays its updates available dialog.
Refer to this image for clarification about OS X update available alert:
I have searched this over the internet, as well as gone through Notification Center's documentation this and this as well.
Is there any undocumented API? or some custom mechanism for detecting click on Other (close) button?
回答1:
While the other (close) button is clearly meant to dismiss the notification, regardless of what its custom caption may indicate, there is no elegant way to get notified when the user dismisses the notification by clicking on the close button.
What you could do, however, is to monitor the default user notification center's deliveredNotifications property: As long as the notification has not yet been dismissed, the array will contain the notification. Once the notification has been dismissed, the array will not contain it anymore.
This could be implemented in a NSUserNotificationCenter delegate method like this:
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
BOOL notificationStillPresent;
do {
notificationStillPresent = NO;
for (NSUserNotification *nox in [[NSUserNotificationCenter defaultUserNotificationCenter] deliveredNotifications]) {
if ([nox.identifier isEqualToString:notification.identifier]) notificationStillPresent = YES;
}
if (notificationStillPresent) [NSThread sleepForTimeInterval:0.20f];
} while (notificationStillPresent);
dispatch_async(dispatch_get_main_queue(), ^{
[self notificationHandlerForNotification:notification];
});
});
}
This code will check if the notification is still there every 200 milliseconds. Once it is gone, the -notificationHandler: method will be called on the main thread, which is just an arbitrary callback method.
In this custom -notificationHandler: method you could check whether NSUserNotificationCenter's didActivateNotification: delegate method has been called for the notification. If it hasn't, the user most likely clicked on the close button of the notification.
This is not failsafe, though, as the user may also have otherwise dismissed the notification, i.e. without clicking on the close button.
回答2:
In Swift 3
func userNotificationCenter(_ center: NSUserNotificationCenter, didDismissAlert notification: NSUserNotification) {
print("dismissed")
}
This is not part of the NSUserNotificationDelegate
but works perfectly
回答3:
In Swift 2.3:
func userNotificationCenter(center: NSUserNotificationCenter, didDeliverNotification notification: NSUserNotification) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
var notificationStillPresent: Bool
repeat {
notificationStillPresent = false
for nox in NSUserNotificationCenter.defaultUserNotificationCenter().deliveredNotifications {
if nox.identifier == notification.identifier {
notificationStillPresent = true
break
}
}
if notificationStillPresent {
let _ = NSThread.sleepForTimeInterval(0.20)
}
} while notificationStillPresent
dispatch_async(dispatch_get_main_queue()) {
self.notificationHandlerFor(notification)
}
}
}
PS: Please also notice that it is the way to detect the dismiss event, which can be triggered in several cases.
- Click the
otherButton
to dismiss - Click the
Clear All
button in Notification Center
PS 2: If you are using deliveryRepeatInterval
, say 1 minute, there are multiple notifications in deliveredNotifications
array, while only one is displayed. The dismissal shall trigger multiple callbacks.
PS 3: Clicking actionButton
will also trigger the dismissal callback
回答4:
This helped me out
func userNotificationCenter(_ center: NSUserNotificationCenter, didActivate notification: NSUserNotification) {
switch (notification.activationType) {
case .none:
print("none CLicked")
break
case .actionButtonClicked:
print("Additional Action Clicked")
break
case .contentsClicked:
print("contents CLicked")
break
case .replied:
print("replied Action Clicked")
break
case .additionalActionClicked:
print("Additional MENU Action Clicked")
break
}
来源:https://stackoverflow.com/questions/21110714/mac-os-x-nsusernotificationcenter-notification-get-dismiss-event-callback