Подтвердить что ты не робот

Уведомление Mac OS X NSUserNotificationCenter об отмене события/обратного вызова

В нашем приложении мы показываем уведомления Notification Center в стиле предупреждений.

Отображение уведомлений работает отлично, а также мы получаем обратный вызов, когда пользователь взаимодействует с уведомлением, либо нажав на уведомление, либо нажав кнопку "Действие".

Однако мы заинтересованы в получении обратного вызова или события, когда пользователь нажимает кнопку "Другие" в уведомлении. Я видел, что MAC OS делает это, когда отображается диалоговое окно доступных обновлений.

Обратитесь к этому изображению, чтобы уточнить доступность оповещения об обновлении OS X:

enter image description here

Я искал это через Интернет, а также просмотрел документацию Notification Center this и .

Есть ли какой-либо недокументированный API? или какой-либо пользовательский механизм для обнаружения нажмите кнопку "Другие" (закрыть)?

4b9b3361

Ответ 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
    }