Swift Nsusernotification Doesn't Show While App Is Active

Swift NSUserNotification doesn't show while app is active

To ensure the notifications are always shown you'll need to set a delegate for NSUserNotificationCenter and implement userNotificationCenter(center:shouldPresentNotification:) -> Bool. The documentation says this message is

Sent to the delegate when the user notification center has decided not
to present your notification.

You can implement the delegate in any class of your choosing. Here is an example:

class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {

func applicationDidFinishLaunching(aNotification: NSNotification) {
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self
}

func userNotificationCenter(center: NSUserNotificationCenter, shouldPresentNotification notification: NSUserNotification) -> Bool {
return true
}

MacOS App Local Notification Not Showing when testing with XCode

I believe that my problem here was asking permission to use UNUserNotification and then using NSUserNotification to create the notification itself, which of course I had not requested permission to use. Requesting permission is now mandatory in Catalina (and perhaps it was in earlier versions of macOS as well.)

So I replaced the generateNotification function with the following and it all works correctly.

let notificationCenter = UNUserNotificationCenter.current();
notificationCenter.getNotificationSettings
{ (settings) in
if settings.authorizationStatus == .authorized
{
//print ("Notifications Still Allowed");
// build the banner
let content = UNMutableNotificationContent();
content.title = summary ;
content.body = title ;
if sound == "YES" {content.sound = UNNotificationSound.default};
// could add .badge
// could add .userInfo

// define when banner will appear - this is set to 1 second - note you cannot set this to zero
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false);

// Create the request
let uuidString = UUID().uuidString ;
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger);

// Schedule the request with the system.
notificationCenter.add(request, withCompletionHandler:
{ (error) in
if error != nil
{
// Something went wrong
}
})
//print ("Notification Generated");
}

removeDeliveredNotification: doesn't

The notification you are attempting to be removed must be in the deliveredNotifications array. Quote the docs for -removeDeliveredNotification:

If the user notification is not in deliveredNotifications, nothing happens.

Your notification may be copied when you call -deliverNotification:, so keeping a reference to that instance and attempting to remove later it may fail. Instead, stash something in the notification's userInfo property so you can identify it, and scan through the deliveredNotifications array to find the notification you want to remove.


Added by Brent

Here's the corrected version of the method in my question. I'm using the original notification's pointer value, casted to an integer, to identify the copy; this isn't foolproof, but it's probably good enough.

- (NSUserNotification*)deliverNotificationWithSound:(NSString*)sound title:(NSString*)title messageFormat:(NSString*)message {
NSUserNotification * note = [NSUserNotification new];

note.soundName = sound;
note.title = title;
note.informativeText = [NSString stringWithFormat:message, NSRunningApplication.currentApplication.localizedName, self.document.displayName];
note.userInfo = @{ @"documentFileURL": self.document.fileURL.absoluteString, @"originalPointer": @((NSUInteger)note) };

[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:note];

// NSUserNotificationCenter actually delivers a copy of the notification, not the original.
// If we want to remove the notification later, we'll need that copy.
for(NSUserNotification * deliveredNote in NSUserNotificationCenter.defaultUserNotificationCenter.deliveredNotifications) {
if([deliveredNote.userInfo[@"originalPointer"] isEqualToNumber:note.userInfo[@"originalPointer"]]) {
return deliveredNote;
}
}

return nil;
}

ObjectiveC - how to use NSUserNotification identifier property

You can delete an existing notification using the NSNotificationCenters removeDeliveredNotification: method.
Just remove and re-add your notification.

Objective-C

[[NSUserNotificationCenter defaultUserNotificationCenter] removeDeliveredNotification:userNotification];
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];

Swift

NSUserNotificationCenter.default.removeDeliveredNotification(userNotification)
NSUserNotificationCenter.default.deliver(userNotification)

I successfully used this technique to show notifications without polluting the notification center.

didReceiveRemoteNotification:fetchCompletionHandler not being called when app is in background and not connected to Xcode

Issue have been fixed in iOS 7.1 Beta 3.
I double checked and I confirm it's working just fine.



Related Topics



Leave a reply



Submit