1

I am trying to connect a pre-existing perl script to the Mac OS 10.8/10.9 notification center.

The following code is what I have tried, and for some reason I can not get it to work:

#!/usr/bin/perl

use strict;
use warnings;
use Foundation;

my $notification = NSUserNotification->alloc()->init();
my $string = NSString->stringWithCString_("Test");
$notification->setTitle_($string);
$notification->setInformativeText_($string);

# the following line seems to be the issue. According to PerlObjCBridge->setTracing(1)
# the value returned from this is \0 and not an object, which is what it should be.
my $center = NSUserNotificationCenter->defaultUserNotificationCenter();

# this should be the line to display the notification, but it doesn't work because
# $center is \0 instead of an object
$center->deliverNotification_($notification);

Any assistance as to why NSUserNotificationCenter->defaultUserNotificationCenter() isn't returning an object?

Also, I realize that I could just call

system(osascript -e 'display notification "test" with title "test"');

But, well, I despise AppleScript. And my initial impression would be that there is more overhead calling the applescript engine then objc, which could be completely unfounded.

Thanks!

  • 1
    Of course after hours of searching I come across this http://stackoverflow.com/questions/11712535/mac-mountain-lion-send-notification-from-cli-app It appears that CLI apps are straight up barred from using notifications... seems kind of silly to me. – antiharmonic Dec 31 '13 at 18:22
  • I am sure it is more about the lack of a bundle than being cli, as you can launch any normal app from the cli. – Grady Player Dec 31 '13 at 22:28

1 Answers1

0

Here's how I solved this problem.

  • Find your "bundle directory" when running a perl script.

    #!/usr/bin/perl
    
    use Foundation;
    
    my $bundle = NSBundle->mainBundle();
    if ($bundle) {
        print $bundle->bundlePath()->cString() . "\n";
        print $bundle->bundleIdentifier()->cString() . "\n";
    } else {
        print "Bundle is not an object.";
    }
    
  • Find an application to hijack the Info.plist (or Create your own Bundle)
  • If hijacking a bundle, create a soft link to the Contents directory of the bundle inside the bundle directory output from the script.
  • If creating your own Bundle, I don't have instructions. But I would presume creating a Contents directory and an Info.plist file with the required elements would work just as well.

I hijacked Microsoft Outlook's bundle, and it showed a notification as if it were from Outlook.

Bradley M Handy
  • 603
  • 6
  • 15