I would like to create a user agent in Objective-C that listens for notifications from the default NSDistributedNotificationCenter
. The agent will not have a GUI. When I create a Cocoa application (I will also be using Distributed Objects, which I think is only in Cocoa) in Xcode, however, Xcode sets the project as a GUI application.
In the main function, I remove the NSApplicationMain(...)
function call to remove the GUI elements from the application. However, now I can't get the thread to wait (listen for) notifications coming in from the NSDistributedNotificationCenter
. The app just starts and quits immediately.
I looked into using the NSRunLoop
from the current NSThread
, however, it seems that NSRunLoop
s only wait on NSPort
s. There's no mention of waiting on NSNotifications
.
NSDistributedNotificationCenter
is Foundation, so you don't need to create a GUI app. You can create a command line template, for example, and run it from terminal. As a very simple example, you could create an example that just prints out every distributed notification it receives below.
To build, copy into an Xcode template for a Foundation command line app, or simply copy into a text file named something like test_note.m and build according to the comments. In this example, the application will never end (CFRunLoopRun()
never returns) and you will have to kill it by hitting CTRL+C from the terminal or killing it with something like kill
or the activity monitor.
// test_build.m
// to build: clang -o test_build test_build.m -framework foundation
#import <Foundation/Foundation.h>
@interface Observer : NSObject
- (void)observeNotification:(NSNotification*)note;
@end
@implementation Observer
- (void)observeNotification:(NSNotification*)note
{
NSLog(@"Got Notification: %@", note);
}
@end
int main (int argc, char const *argv[])
{
@autoreleasepool {
Observer* myObserver = [[Observer alloc] init];
[[NSDistributedNotificationCenter defaultCenter] addObserver:myObserver selector:@selector(observeNotification:) name:nil object:nil];
CFRunLoopRun();
}
return 0;
}