Programmieren mit Swift - Für macOS und iOS
Programmieren mit Swift - Für macOS und iOS
NSUserNotification - Weitere Konfiguration

Wird für ein NSUserNotification-Objekt die Eigenschaft deliveryDate gesetzt und die Nachricht anschließend mit scheduleNotification: an die Mitteilungszentrale übergeben, ist es möglich, Nachrichten zeitverzögert anzuzeigen. So können Meldungen sogar dann angezeigt werden, wenn die absendende Anwendung bereits beendet wurde.
// Mitteilung erst in 10 Sekunden anzeigen
notification.deliveryDate = [NSDate dateWithTimeIntervalSinceNow:10];
   
// Benachrichtigung an das Nachrichtencenter übergeben.
[[NSUserNotificationCenter defaultUserNotificationCenter]scheduleNotification:
    notification];
Soll eine termingesteuerte Mitteilung vor ihrer Fälligkeit wieder gelöscht werden, funktioniert dies über den Aufruf von removeScheduledNotification:. Allerdings muss man bei dieser Methode genau die NSUserNotification übergeben, die zuvor an die Mitteilungszentrale übergeben wurden. Hat man die Anwendung zwischenzeitlich beendet und neu gestartet, ist dies nicht ohne weiteres möglich. Glücklicherweise lassen sich alle im NSUserNotificationCenter hinterlegten Mitteilungen über die Eigenschaft scheduledNotifications abfragen. Mit einer Schleife und den richtigen Vergleich ist es dann möglich, eine abgesendete Nachricht wieder zu finden und aus der Mitteilungszentrale zu entfernen.
NSUserNotificationCenter *center
= [NSUserNotificationCenter defaultUserNotificationCenter];

// Alle Mitteilungen dieser Anwendung holen
NSArray *notifications = center.scheduledNotifications;
   
for (NSUserNotification *note in notifications)
{
    if ([note.title isEqualToString:@"Überschrift"])
    {
        // Mitteilung wieder entfernen
        [center removeScheduledNotification:note];
        break;
    }
}
Sofern die Anwendung beim Zustellen der Nachricht noch läuft, kann dieses Ereignis im Programmcode leicht überprüft werden. Das zum Delegate des NSUserNotificationCenter bestimmt Objekt erhält eine userNotificationCenter: didDeliverNotification:-Nachricht, bei der auch die Mitteilung als Parameter mit übergeben wird. Diese Methode wird aufgerufen, bevor die Nachricht zur Anzeige gebraucht wird. Setzten Sie im Code einen Haltepunkt und Sie werden das Mitteilungsfenster erst sehen, wenn der Programmablauf die Methode wieder verlassen hat.
- (void)userNotificationCenter:(NSUserNotificationCenter *)center
  didDeliverNotification:(NSUserNotification *)notification
{
    NSLog(@"Zugestellt: %@",notification.title);
}
Soll ein Programm selbst bestimmen, ob es seine Mitteilungen im Stil Hinweis mit zwei Schaltflächen und nicht als Banner anzeigt, muss in der info.plist des Projektes der Schlüssel NSUserNotificationAlertStyle mit dem Wert alert eingefügt werden. Allerdings hat diese Konfiguration nur bei Code-signierten Anwendung tatsächlich Auswirkungen.
stacks_image_A12D8584-4300-445B-B741-E600C8834328
Die Beschriftungen der Button können dann aus dem Code verändert werden.
notification.hasActionButton = YES;
notification.otherButtonTitle = @"Schließen";
notification.actionButtonTitle = @"Aktion";
Durch Anklicken des otherButton wird die Mitteilung nur geschlossen, wohingegen der action Button zusätzliche eine Nachricht zurück an die Anwendung schickt. Die kann dort durch die Methode userNotificationCenter: didActivateNotification: entgegengenommen werden.
- (void)userNotificationCenter:(NSUserNotificationCenter *)center
  didActivateNotification:(NSUserNotification *)notification
{
    NSBeep();
}
stacks_image_95F2EDFE-B327-4A4A-BC47-E5EAE19FEB41
Der Aufruf von userNotificationCenter: didActivateNotification: funktioniert allerdings nur, wenn die Anwendung zum Zeitpunkt des Anklickens noch ausgeführt wird. Ist das nicht der Fall, wird das Programm automatisch neu gestartet und die Mitteilung an applicationDidFinishLaunching mit übergeben. Über den Schlüssel NSApplicationLaunchUserNotificationKey kann die NSUserNotification aus dem userInfo-Dictionary der NSNotification ermittelt werden.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    if (aNotification != nil)
    {
        NSUserNotification *userNotification =
        [aNotification.userInfo
        objectForKey:@"NSApplicationLaunchUserNotificationKey"];
        if ([userNotification.title isEqualToString:@"Überschrift"])
        {
            NSBeep();
        }
    }

    [[NSUserNotificationCenter defaultUserNotificationCenter]
     setDelegate:self];
}
Wird für ein NSUserNotification-Objekt die Eigenschaft hasReplyButton auf YES gesetzt, erhält die Mitteilung statt des actionButton eine Schaltfläche mit der Beschriftung Antworten.
stacks_image_EB517525-1D86-4AE7-BAC0-0356FB4CC76C
So erhält der Anwender die Möglichkeit, direkt über die Mitteilung Informationen an das Programm zurück zu geben. Der eingegeben Text ist dann ebenfalls Teil der Mitteilung, die an die Anwendung gesendet wird und kann über die Eigenschaft response.string ausgelesen werden. Über den activationType kann man sogar ermitteln, auf welchem Weg die Methode aufgerufen wurde, falls die Anwendung verschiedene Typen von Mitteilungen implementiert.
stacks_image_B7E0BD7D-C117-422D-A422-1E6165858FAE
- (void)userNotificationCenter:(NSUserNotificationCenter *)center
        didActivateNotification:(NSUserNotification *)notification
{
    if (notification.activationType ==
        NSUserNotificationActivationTypeReplied)
    {
        NSString* reply = notification.response.string;
        NSLog(@"Reply: %@",reply);
    }
}