2

I'm not sure if I got something wrong but from the examples I could find. I wrote that little helloworld.

#import <Foundation/Foundation.h>
#import <Foundation/NSUserNotification.h>


int main (int argc, const char * argv[])
{
    NSUserNotification *userNotification = [[NSUserNotification alloc] init];
    userNotification.title = @"Some title";
    userNotification.informativeText = @"Some text";

    [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];

    return 0;
}

I compile it with:

cc -framework Foundation -o app main.m

It compiles and I can execute it but it won't show anything. For some reasons, nothing gets presented. I read that Notifications may not get displayed if the application is the main actor. How can I make it show Notification?

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99

5 Answers5

7

set a delegate and override

- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center 
                               shouldPresentNotification:(NSUserNotification *)notification {
  return YES;
}
ocodo
  • 29,401
  • 18
  • 105
  • 117
lxDriver
  • 79
  • 1
1

For a complete example in Objective-C and Swift:

We need to provide a NSUserNotificationCenterDelegate, in the simplest case we can use AppDelegate for this

Objective-C

We need to modify AppDelegate provide NSUserNotificationCenterDelegate method. From a clean AppDelegate (which looks like this...)

@interface AppDelegate ()

We'd modify it to be:

@interface AppDelegate () <NSUserNotificationCenterDelegate>

Now we can provide the required delegate method inside @implementation AppDelegate

- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center 
                               shouldPresentNotification:(NSUserNotification *)notification {
  return YES;
}

Swift 4

You can use an extension of AppDelegate to provide NSUserNotificationCenterDelegate methods:

extension AppDelegate: NSUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: NSUserNotificationCenter, shouldPresent notification: NSUserNotification) -> Bool {
        return true
    }
}
ocodo
  • 29,401
  • 18
  • 105
  • 117
1

Be sure to assign a new identifier for any new notification. A notification will only show once, unless a new identifier is used or the user clears their notification history.

Berik
  • 7,816
  • 2
  • 32
  • 40
0

I know it's an old question - but as there may be people looking for an answer how to do this in Python & PyObjC I will post the correct syntax here (as it's one of the top google results). As I can't comment on imp's comment I will post this as another answer.

It's possible to do the same in Python with pyobjc this way:

def userNotificationCenter_shouldPresentNotification_(self, center, notification):
    return True

Full class would look like this:

from Cocoa import NSObject
import objc

class MountainLionNotification(NSObject):
    """ MacOS Notifications """
    # Based on http://stackoverflow.com/questions/12202983/working-with-mountain-lions-notification-center-using-pyobjc

    def userNotificationCenter_shouldPresentNotification_(self, center, notification):
        return True

    def init(self):

        self = super(MountainLionNotification, self).init()
        if self is None: return None

        # Get objc references to the classes we need.
        self.NSUserNotification = objc.lookUpClass('NSUserNotification')
        self.NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')

        return self

    def clearNotifications(self):
        """Clear any displayed alerts we have posted. Requires Mavericks."""

        NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
        NSUserNotificationCenter.defaultUserNotificationCenter().removeAllDeliveredNotifications()

    def notify(self, title="", subtitle="", text="", url=""):
        """Create a user notification and display it."""

        notification = self.NSUserNotification.alloc().init()
        notification.setTitle_(str(title))
        notification.setSubtitle_(str(subtitle))
        notification.setInformativeText_(str(text))
        # notification.setSoundName_("NSUserNotificationDefaultSoundName")
        notification.setHasActionButton_(False)
        notification.setActionButtonTitle_("View")
        # notification.setUserInfo_({"action":"open_url", "value": url})

        self.NSUserNotificationCenter.defaultUserNotificationCenter().setDelegate_(self)
        self.NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)

        # Note that the notification center saves a *copy* of our object.
        return notification
Pylinux
  • 11,278
  • 4
  • 60
  • 67
0

I followed the code on here but was unable to get a notification to work. It turned out that because I was on multiple monitors I needed to check the "When mirroring or sharing the display" option to get the alerts to present themselves. After that the python code worked.

enter image description here

GoBig06
  • 255
  • 2
  • 13