wetjosh
wetjosh

Reputation: 6398

Open Cocoa App via URL Scheme

My question is identical to this question but it hasn't been updated in a while and Swift has changed a lot since it was asked so the answer might need to be refreshed. All I want to do is capture the url used to open my cocoa app, but the code never gets executed in my handler function. Errors are thrown in Console.app when I launch my application via the custom url scheme. Here are the errors:

-[MyApp.AppDelegate handleGetURLEvent:replyEvent:]: unrecognized selector sent to instance 0x60c0000039b0
-[MyApp.AppDelegate handleGetURLEvent:replyEvent:]: unrecognized selector sent to instance 0x60c0000039b0
    OSErr AERemoveEventHandler(AEEventClass, AEEventID, AEEventHandlerUPP, Boolean)(spec,phac handler=0x7fff576b7f15 isSys=YES) err=0/noErr
-[MyApp.AppDelegate handleGetURLEvent:replyEvent:]: unrecognized selector sent to instance 0x60c0000039b0
-[MyApp.AppDelegate handleGetURLEvent:replyEvent:]: unrecognized selector sent to instance 0x60c0000039b0
    OSErr AERemoveEventHandler(AEEventClass, AEEventID, AEEventHandlerUPP, Boolean)(GURL,GURL handler=0x7fff5661d680 isSys=YES) err=0/noErr
LSExceptions shared instance invalidated for timeout.

And my bare bones app:

Create a new Cocoa app named MyApp. In Info > URL Types, enter my app's bundle identifier in the Identifier field, and blue (for example) in the URL Schemes field. Add the following two functions to the AppDelegate class:

func applicationWillFinishLaunching(_ notification: Notification) {
    let appleEventManager: NSAppleEventManager = NSAppleEventManager.shared()
    appleEventManager.setEventHandler(self, andSelector: Selector(("handleGetURLEvent:replyEvent:")), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}

func handleGetURLEvent(event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) {
    NSLog("heyo!")
}

Build and run my app. Quit it, then in Safari type blue://whatever in the address bar and hit return. The app opens, but the NSLog doesn't show up in Console.app and instead I get the errors I mentioned above. I would love to be stuck on how to parse the url, but I can't even get to that part yet. I'm running Xcode 8.3.3 (8E3004b) and Swift 3.1. Do you all get the same result as me? Am I calling the handler function wrong?

Upvotes: 0

Views: 1891

Answers (2)

UKDataGeek
UKDataGeek

Reputation: 6882

@Lucas Derraugh is a genius - I looked all over for that solution. Thanks!

One addition on Swift 4 Xcode prompted me to add @objc to the function so I had:

  func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Register for Call back URL events
        let aem = NSAppleEventManager.shared();
        aem.setEventHandler(self, andSelector: #selector(AppDelegate.handleGetURLEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))

    }

  @objc func handleGetURLEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {

    let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue!
        let url = URL(string: urlString!)!
       // DO what you will you now have a url.. 

    }

Upvotes: 5

Lucas Derraugh
Lucas Derraugh

Reputation: 7049

Try swapping out the Selector(("handleGetURLEvent:replyEvent:")) with #selector(AppDelegate.handleGetURLEvent(event:replyEvent:)). The #selector macro will verify the existence of the method at compile time so it should be using the correct selector at runtime.

As an aside

-[MyApp.AppDelegate handleGetURLEvent:replyEvent:]: unrecognized selector sent to instance 0x60c0000039b0

is saying that handleGetURLEvent:replyEvent: was called on AppDelegate, but it doesn't respond to this message, meaning that either the selector was spelled incorrectly or it was sent to the wrong object. In this case, probably the spelled incorrectly case because the Selector() syntax is Obj-C so it's harder to know what the equivalent is in Swift. This is why you should use #selector.

Upvotes: 3

Related Questions