This is what I had to do. Note the runloop like that has a very tiny delay. It's necessary in order to see that notification.
NSUserNotification *n = [[NSUserNotification alloc] init];
n.title = @"My Title";
n.subtitle = @"my subtitle";
n.informativeText = @"some informative text";
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:n];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
However, you may notice with this that it shows a terminal icon instead of a nice icon. To fix that, there's a poorly documented technique. Unfortunately with this technique, though, I don't know how to link it to my own custom icon -- only to an installed application icon.
Add an Info.plist file to your project. If your project is called acme, usually XCode creates a yellow folder in your project called acme and puts your files there. So, add an Info.plist there, and don't forget to capitalize that I in Info. BTW, don't worry about distributing that Info.plist file with your CLI app -- it gets bundled automatically into the binary itself.
Next, open the Info.plist and add a new item. It will prompt you for some default items. Choose Bundle Identifier. Now, on the value part of this key, set it to a valid bundle identifier for an installed application in the Applications folder. So for me, my LaunchDaemon was the command line app that needed to send notifications, and I had a GUI app that mated with it in the /Applications folder called (for sake here) as /Applications/Acme.app. So, inside the Acme.app's Info.plist file, I had my existing bundle identifier of com.acme.myapp. As well, that GUI application already had an icon on it. So, I set my value in my CLI app's Info.plist file bundle identifier to com.acme.myapp so that it would use that icon. Now, you could also set this to com.apple.finder if you wanted, and it will grab the Finder icon. (BTW, if you know how to bundle an icon with the CLI app itself, rather than borrowing it from another installed application, then please let me know.)
Now, go into your Build Settings and use the Search box and type "infoplist". You'll see an item called "Info.plist File". Set it to the relative folder path of your file. So, remember when I mentioned that my project had a yellow "acme" folder and my Info.plist file was inside that? So, all I had to do was type "acme/Info.plist" under the second column (the left one said "Resolved") and the third column.
Now, while in Build Settings, search on "create info". You'll see an entry "Create Info.plist Section in Binary". In the second and third columns, set it to Yes.
Another problem with this issue is that when you click the alert, it launches the command line app instead of a GUI application that you might want to load.
deliverNotification:
is any different. – HectaredeliverNotification
is the only way that I get this to work in an App bundle. Good call on that. – Renfrow