I recently built a small OSX utility that sits in the menu bar and polls your Collabable account for new discussions, one of the final feature i needed to implement was Growl support.
The brief was simple enough, two type of growl notification were required, a simple digest of all discussions when you first logged in and then a specific “New Discussion” notification when a new discussion came in.
Adding the Growl SDK to your project
The growl SDK is a simple Cocoa framework that you can drop in to your xCode project, download the SDK from http://growl.info/downloads (its at the bottom of the page).
Once downloaded locate and unzip, the unzipped folder will contain a number of things but we are looking for the Growl.framework folder:
Simply drag this folder in to your Frameworks group in your xCode project:
xCode will ask you how you want to copy the framework in, check the copy to destination box so the framework is saved in to your project folder.
You now need to configure xCode to link the Growl framework in to your project and copy the relevent files in to the application bundle, open up the build phase section and make sure that the “Link Binary With Libraries” includes the Growl.framework, xCode should have done this bit for you when you dragged the framework in, but its worth checking just in case, if its not there click the “+” and select it from the list.
Next we want to tell xCode to copy the framework into our bundle, to do this you need to locate the “Copy Files” section in the Build Phases section, if you don’t yet have a “Copy Files” section simply click the “Add Build Phase” button (bottom right) and select “Add Copy Files”. Once you have located the “Copy Files” section change the destination to “Frameworks” and drag in your Growl.framework:
Hit cmd-B to build your project and thats Growl ready to use in your application.
Using the Growl SDK in your application
The basics of using growl are as simple as, impementing a protocol in your app delegate and telling growl to display something, its really that easy, so lets set up our app delegate.
open up your AppDelegate.h (mine is called ABAppDelegate.h, your might have another name), add an import to the growl header file and implement the GrowlApplicationBridgeDelegate on your app delegate class:
Open up your AppDelegate.m file and implement the following method (see the Growl Docs for more info):
#pragma mark - Growl 1.3.1 SDK - -(NSDictionary *)registrationDictionaryForGrowl{ NSArray *notifications; notifications = [NSArray arrayWithObjects: C_COLLABABLE_GROWL_NOTIFICATION, C_COLLABABLE_GROWL_NOTIFICATION_DIGEST, nil]; NSDictionary *dict; dict = [NSDictionary dictionaryWithObjectsAndKeys: notifications, GROWL_NOTIFICATIONS_ALL, notifications, GROWL_NOTIFICATIONS_DEFAULT, nil]; return (dict); }
registrationDictionaryForGrowl is the only Required method in the GrowlApplicationBridgeDelegate protocol and its simply a way of telling growl about the types of notifications your going to be sending. I’m using two constants because i want to use them later when i finally dispatch a notification.
Next up we need to tell Growl that we are going to be its delegate by sending a message to setGrowlDelegate:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { [GrowlApplicationBridge setGrowlDelegate:self]; }
Thats all the Growl plumbing done, your now free to stat sending notifications.
Dispatching a Growl Notification
Once you app delegate is set up to act as the Delegate for Growl by implementing the GrowlApplicationBridgeDelegate you can dispact notifications from anywhere in your application, for this project I have a separate controller that receives messages whenever a new discussion comes in, however you can dispatch the notifications from any class that suites your needs.
To send a growl notification you simply need to call :
+ (void) notifyWithTitle:(NSString *)title description:(NSString *)description notificationName:(NSString *)notifName iconData:(NSData *)iconData priority:(signed int)priority isSticky:(BOOL)isSticky clickContext:(id)clickContext;
For my project I had the following in my DisucssionController:
[GrowlApplicationBridge notifyWithTitle:@"Collabable" description:[NSString stringWithFormat:@"%d Discussions, %d Unread", data.count, unreadCount] notificationName:C_COLLABABLE_GROWL_NOTIFICATION_DIGEST iconData:[[NSImage imageNamed:@"CollabableGrowl.png"] TIFFRepresentation] priority:0 isSticky:NO clickContext:@"DIGEST"];
Most of that message is obvious however you will notice that i have supplied an image to iconData, this can me nil which will tell growl to use your application icon, however i felt that the growl icon needed a but more work to make it pleasing on the eye in the context of a growl notification, so i specified my own Growl specific image. I also pass an NSString in to clickContext of @”Digest” this is my payload that when clicked will get passed in to the click handler if you choose to implement one, again you can send nil to this if you not implementing the Click handler.
And thats it, sending that message to the GrowlApplicationBridge will dispatch a notification:
Handling Clicks
The final piece of the puzzle is handling what happens when your user clicks on the notification, again this is super simple and is done back in your AppDelegate by implementing the following method from the GrowlApplicationBridgeDelegate protocol:
- (void) growlNotificationWasClicked:(id)clickContext;
My implementation is like this:
-(void)growlNotificationWasClicked:(id)clickContext{ if ([(NSString *)clickContext isEqualToString:@"DIGEST"] ){ self.popoutViewcontroller.popupVisible = true; }else{ [[NSNotificationCenter defaultCenter] postNotificationName:COLLAB_SHOULD_OPEN_URL object: self userInfo:[NSDictionary dictionaryWithObject:clickContext forKey:@"discussionId"]]; } }
I’m basically using the clickContext to determine which type of notification was clicked (remember my brief was for two types of notification) and acting accordingly, if its a Digest I open up the Collabable popout window otherwise i know its a discussion so i send a notification that my app will collect and process.
Thats it we have implemented Growl notifications in to our OSX application, and it was seriously east, in fact this blog article took longer to write than the actual implementation… Enjoy






