Уведомление Mac OS X NSUserNotificationCenter об отмене события/обратного вызова
В нашем приложении мы показываем уведомления Notification Center в стиле предупреждений.
Отображение уведомлений работает отлично, а также мы получаем обратный вызов, когда пользователь взаимодействует с уведомлением, либо нажав на уведомление, либо нажав кнопку "Действие".
Однако мы заинтересованы в получении обратного вызова или события, когда пользователь нажимает кнопку "Другие" в уведомлении. Я видел, что MAC OS делает это, когда отображается диалоговое окно доступных обновлений.
Обратитесь к этому изображению, чтобы уточнить доступность оповещения об обновлении OS X:
![enter image description here]()
Я искал это через Интернет, а также просмотрел документацию Notification Center this и .
Есть ли какой-либо недокументированный API? или какой-либо пользовательский механизм для обнаружения нажмите кнопку "Другие" (закрыть)?
Ответы
Ответ 1
В то время как другая (закрывающая) кнопка явно предназначена для отклонения уведомления, независимо от того, что может указывать его пользовательская подпись, нет элегантного способа получить уведомление, когда пользователь отклоняет уведомление, нажав кнопку закрытия.
Тем не менее, вы можете следить за предоставленным центром уведомлений по умолчанию, указанным в уведомлении: Нет. Пока уведомление еще не было отклонено, массив будет содержать уведомление. Как только уведомление будет отклонено, массив больше не будет содержать его.
Это может быть реализовано в методе делегата 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];
});
});
}
Этот код проверяет, сохраняется ли уведомление каждые 200 миллисекунд. Как только он исчезнет, в основном потоке будет вызываться метод -notificationHandler: method, который является просто методом обратного вызова.
В этом обычном методе -notificationHandler: вы можете проверить, был ли NSUserNotificationCenter didActivateNotification: метод делегирования был вызван для уведомления. Если этого не произошло, пользователь, скорее всего, нажал кнопку закрытия уведомления.
Это не является отказоустойчивым, хотя пользователь также может отклонить уведомление иначе, не нажав кнопку закрытия.
Ответ 2
В Swift 3
func userNotificationCenter(_ center: NSUserNotificationCenter, didDismissAlert notification: NSUserNotification) {
print("dismissed")
}
Это не часть NSUserNotificationDelegate
, но отлично работает
Ответ 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: Также обратите внимание, что это способ обнаружить событие отклонения, которое может быть запущено в нескольких случаях.
- Нажмите
otherButton
, чтобы отклонить
- Нажмите кнопку
Clear All
в Центре уведомлений
PS 2: Если вы используете deliveryRepeatInterval
, скажем, 1 минуту, в массиве deliveredNotifications
есть несколько уведомлений, а отображается только один. Увольнение должно инициировать множественные обратные вызовы.
PS 3: нажатие actionButton
также вызовет обратный вызов увольнения
Ответ 4
Это помогло мне
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
}