This is the Cocoa version of this question:
AEInstallEventHandler handler not being called on startup
Here's my Info.plist protocol registration:
...
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>My Protocol</string>
<key>CFBundleURLIconFile</key>
<string>myicon</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
Here's where I set the method to listen for the kInternetEventClass/kAEGetURL event when a browser link is clicked with the link "myapp://unused/?a=123&b=456":
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(getURL:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
...
}
Here's the handler method:
- (void)getURL:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)reply
{
[[[event paramDescriptorForKeyword:keyDirectObject] stringValue] writeToFile:@"/testbed/complete_url.txt" atomically:YES];
}
Here's the test web link:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
</head>
<body>
<a href="myapp://open/?a=123&b=456">Open My App</a>
</body>
</html>
This all works great if the application is already running.
The handler method is called and the complete url is captured.
However, if the app is not yet running the same link will launch the app, but the handler will not be invoked — which makes sense since the handler had not yet been bound to the event.
Those arguments in the URL are important for our application to coordinate with the webapp. Although the vast majority of the time our application will already be running when this click occurs, it is reasonable to expect that in some cases it will not.
I've tried inspecting the environment and process invocation arguments and I do not see the URL in either of them.
Anyone know how we can capture this URL reliably, even when our application isn't already running when the browser click happens?
Apple’s SimpleScriptingPlugin sample registers the handler in applicationWillFinishLaunching:
, which is probably cleaner than using init
. (And like mikker said, the handler gets called before applicationDidFinishLaunching:
.)
I just faced this exact problem. I don't know if it's the proper solution but you can register the event handler in the app delegate's init
-method instead.
// in AppDelegate.m
- (id)init
{
self = [super init];
if (self) {
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
return self;
}
One thing to note though is that handleURLEvent:withReplyEvent
get's called before applicationDidFinishLaunching:
if the app is started by an URL Scheme.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With