Search code examples
macoscocoaurl-schemeappkit

How to handle with a default URL scheme


I want to build URI (or URL scheme) support in my app.

I do a LSSetDefaultHandlerForURLScheme() in my + (void)initialize and I setted the specific URL schemes also in my info.plist. So I have URL schemes without Apple Script or Apple Events.

When I call myScheme: in my favorite browser the system activates my app.

The problem is, how to handle the schemes when they are called. Or better said: How can I define what my app should do, when myScheme: is called.

Is there a special method that I have to implement or do I have to register one somewhere?


Solution

  • As you are mentioning AppleScript, I suppose you are working on Mac OS X.

    A simple way to register and use a custom URL scheme is to define the scheme in your .plist:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>URLHandlerTestApp</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>urlHandlerTestApp</string>
            </array>
        </dict>
    </array>
    

    To register the scheme, put this in your AppDelegate's initialization:

    [[NSAppleEventManager sharedAppleEventManager]
        setEventHandler:self
            andSelector:@selector(handleURLEvent:withReplyEvent:)
          forEventClass:kInternetEventClass
             andEventID:kAEGetURL];
    

    Whenever your application gets activated via URL scheme, the defined selector gets called.

    A stub for the event-handling method, that shows how to get the URL string:

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

    Apple's documentation: Installing a Get URL Handler

    Update I just noticed a problem for sandboxed apps that install the event handler in applicationDidFinishLaunching:. With enabled sandboxing, the handler method doesn't get called when the app is launched by clicking a URL that uses the custom scheme. By installing the handler a bit earlier, in applicationWillFinishLaunching:, the method gets called as expected:

    - (void)applicationWillFinishLaunching:(NSNotification *)aNotification
    {
        [[NSAppleEventManager sharedAppleEventManager]
            setEventHandler:self
                andSelector:@selector(handleURLEvent:withReplyEvent:)
              forEventClass:kInternetEventClass
                 andEventID:kAEGetURL];
    }
    
    - (void)handleURLEvent:(NSAppleEventDescriptor*)event
            withReplyEvent:(NSAppleEventDescriptor*)replyEvent
    {
        NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]
                            stringValue];
        NSLog(@"%@", url);
    }
    

    On the iPhone, the easiest way to handle URL-scheme activation is, to implement UIApplicationDelegate's application:handleOpenURL: - Documentation