Search code examples
c++objective-cgrowl

Set delegate to an instance of my class?


I have a c++/obj c set of files to create a sort of C++ wrapper for Growl (which is Obj C) however I am stuck on one part. I need to set a Growl Delegate to something inside my Obj C class so that the registration gets called.

This is my .mm

#import "growlwrapper.h"

@implementation GrowlWrapper
- (NSDictionary *) registrationDictionaryForGrowl {
    return [NSDictionary dictionaryWithObjectsAndKeys:
            [NSArray arrayWithObject:@"Upload"], GROWL_NOTIFICATIONS_ALL,
            [NSArray arrayWithObject:@"Upload"], GROWL_NOTIFICATIONS_DEFAULT
            , nil];
}
@end

void showGrowlMessage(std::string title, std::string desc) {
    std::cout << "[Growl] showGrowlMessage() called." << std::endl;
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [GrowlApplicationBridge setGrowlDelegate: @""];
    [GrowlApplicationBridge
        notifyWithTitle: [NSString stringWithUTF8String:title.c_str()]
        description: [NSString stringWithUTF8String:desc.c_str()]
        notificationName: @"Upload"
        iconData: nil
        priority: 0
        isSticky: YES
        clickContext: nil
    ];
    [pool drain];
}

int main() {
    showGrowlMessage("Hello World!", "This is a test of the growl system");
    return 0;
}

and my .h

#ifndef growlwrapper_h
#define growlwrapper_h

#include <string>
#include <iostream>
#include <Cocoa/Cocoa.h>
#include <Growl/Growl.h>

using namespace std;

void showGrowlMessage(std::string title, std::string desc);
int main();

#endif

@interface GrowlWrapper : NSObject <GrowlApplicationBridgeDelegate>

@end

now as you can see my [GrowlApplicationBridge setGrowlDelegate: @""]; is being set to an empty string, I need to set it to something so that the registrationDictionaryForGrowl gets called, which is currently not being called.

But I can't figure out how to do it. Any help?


Solution

  • You need to create an instance of GrowlWrapper and pass this as the delegate to the setGrowlDelegate: method. You only want to do this once in your application so setting it each time you call showGrowlMessage is not ideal. You'll also want to keep a strong reference to this GrowlWrapper so you can release it when you are done with it or so that it stays valid if you are using ARC. So conceptually you'll want something like the following on startup:

    growlWrapper = [[GrowlWrapper alloc] init];
    [GrowlApplicationBridge setGrowlDelegate:growlWrapper];
    

    And on shutdown:

    [GrowlApplicationBridge setGrowlDelegate:nil];
    [growlWrapper release];    // If not using ARC