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.
但是,当用户点击通知中的“其他”按钮时,我们有兴趣获取回调或事件。我看到MAC OS在显示其可用更新对话框时执行此操作。
Refer to this image for clarification about OS X update available alert:
有关OS X更新可用警报的说明,请参阅此图像:
I have searched this over the internet, as well as gone through Notification Center's documentation this and this as well.
我通过互联网搜索了这个,并且通过了Notification Center的文档和这个。
Is there any undocumented API? or some custom mechanism for detecting click on Other (close) button?
有没有未记录的API?或一些自定义机制检测点击其他(关闭)按钮?
4 个解决方案
#1
9
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.
但是,您可以执行的操作是监视默认用户通知中心的deliverNotifications属性:只要通知尚未解除,阵列就会包含通知。通知被取消后,阵列将不再包含它。
This could be implemented in a NSUserNotificationCenter delegate method like this:
这可以在NSUserNotificationCenter委托方法中实现,如下所示:
- (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.
此代码将检查通知是否仍然每200毫秒。一旦它消失,将在主线程上调用-notificationHandler:方法,这只是一个任意的回调方法。
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.
在此自定义-notificationHandler:方法中,您可以检查是否已为通知调用NSUserNotificationCenter的didActivateNotification:委托方法。如果没有,用户很可能点击了通知的关闭按钮。
This is not failsafe, though, as the user may also have otherwise dismissed the notification, i.e. without clicking on the close button.
然而,这不是故障保护,因为用户也可能已经解除了通知,即没有点击关闭按钮。
#2
2
In Swift 3
在Swift 3中
func userNotificationCenter(_ center: NSUserNotificationCenter, didDismissAlert notification: NSUserNotification) {
print("dismissed")
}
This is not part of the NSUserNotificationDelegate
but works perfectly
这不是NSUserNotificationDelegate的一部分,但效果很好
#3
1
In Swift 2.3:
在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.
PS:请注意,这是检测解雇事件的方法,可以在几种情况下触发。
- Click the
otherButton
to dismiss - 单击otherButton以关闭
- 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 2:如果您使用deliveryRepeatInterval,比如1分钟,deliverNotifications数组中有多个通知,而只显示一个。解雇应触发多次回调。
PS 3: Clicking actionButton
will also trigger the dismissal callback
PS 3:单击actionButton也会触发解雇回调
#4
1
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
}
#1
9
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.
但是,您可以执行的操作是监视默认用户通知中心的deliverNotifications属性:只要通知尚未解除,阵列就会包含通知。通知被取消后,阵列将不再包含它。
This could be implemented in a NSUserNotificationCenter delegate method like this:
这可以在NSUserNotificationCenter委托方法中实现,如下所示:
- (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.
此代码将检查通知是否仍然每200毫秒。一旦它消失,将在主线程上调用-notificationHandler:方法,这只是一个任意的回调方法。
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.
在此自定义-notificationHandler:方法中,您可以检查是否已为通知调用NSUserNotificationCenter的didActivateNotification:委托方法。如果没有,用户很可能点击了通知的关闭按钮。
This is not failsafe, though, as the user may also have otherwise dismissed the notification, i.e. without clicking on the close button.
然而,这不是故障保护,因为用户也可能已经解除了通知,即没有点击关闭按钮。
#2
2
In Swift 3
在Swift 3中
func userNotificationCenter(_ center: NSUserNotificationCenter, didDismissAlert notification: NSUserNotification) {
print("dismissed")
}
This is not part of the NSUserNotificationDelegate
but works perfectly
这不是NSUserNotificationDelegate的一部分,但效果很好
#3
1
In Swift 2.3:
在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.
PS:请注意,这是检测解雇事件的方法,可以在几种情况下触发。
- Click the
otherButton
to dismiss - 单击otherButton以关闭
- 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 2:如果您使用deliveryRepeatInterval,比如1分钟,deliverNotifications数组中有多个通知,而只显示一个。解雇应触发多次回调。
PS 3: Clicking actionButton
will also trigger the dismissal callback
PS 3:单击actionButton也会触发解雇回调
#4
1
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
}