views:

25

answers:

1

My Cocoa application needs to handle Get URL events. I think I correctly followed the steps in this answer to modify Info.plist and write & register a URL handler method.

Problems:

  1. When I go mytesturl://anything in Safari while my app is running, it pops up a window asking if I want to open my app. And if I say yes, nothing seems to happen except that an icon appears for an instant in the dock. So it might be trying to launch another instance of my app instead of sending a message to the running instance?

  2. When I do the same in Firefox, it pops up a window asking me to choose an application. So custom URL protocols are not expected to work in all browsers?

Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
    ...
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>My test URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>mytesturl</string>
            </array>
        </dict>
    </array>
     ...
</dict>
</plist>

Source code:

#import <Cocoa/Cocoa.h>
#include <stdio.h>

@interface Test : NSObject
{
}
- (void)test;
- (void)handleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; 
@end

@implementation Test
- (void)test
{
    NSLog(@"Started..."); 
    char c; 
    scanf("%c", &c); 
}

- (void)handleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
    NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]];
    NSLog(@"url = %@", url); 
}
@end

int main(int argc, char *argv[])
{
    Test *app=[[Test alloc] init];
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:app andSelector:@selector(handleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];

    [app test];

    return 0;   
}
+1  A: 

NSAppleEventManager requires an NSApplication instance in order to function.

Try making Test a subclass of NSApplication, and change main to something like this:

 id app = [NSApplication sharedApplication];
 [[NSAppleEventManager sharedAppleEventManager] setEventHandler:app andSelector:@selector(handleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
 [app run];
smokris