Support URL schemes in macOS application

Viewed 151

There are several (old) questions on this subject, but none of the solutions worked for me, so here's the question: How to add a URL scheme, so it will be possible to open my app via the browser?

I did the following:

  1. Added the required info to the info.plist:

enter image description here

  1. I Added those functions:
func applicationWillFinishLaunching(_ notification: Notification) {
     NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(handleEvent(_:with:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}

@objc func handleEvent(_ event: NSAppleEventDescriptor, with replyEvent: NSAppleEventDescriptor) {
     NSLog("at handleEvent")
}
  1. I also tried to add this function:
func application(_ application: NSApplication, open urls: [URL]) {
    for url in urls {
        NSLog("url:\(url)")
    }
}

None of the above worked. I have a webpage that redirect with MyAppLogin://test but nothing happens. It doesn't matter if the app is open or closed (I want it to work in both cases)

Any idea what's the problem here?

Edit: Two more details:

  1. The app is sandboxed
  2. I'm running it via Xcode (so the installation is not at the 'Applications' folder)
1 Answers

One year later, this is how I made it work:

  1. Add this to your AppDelegate:
func applicationWillFinishLaunching(_ notification: Notification) {
        let appleEventManager: NSAppleEventManager = NSAppleEventManager.shared()
        appleEventManager.setEventHandler(self, andSelector: #selector(handleGetURLEvent(_:withReplyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
  1. Add this, to parse the URL and do whatever you want:
@objc func handleGetURLEvent(_ event: NSAppleEventDescriptor, withReplyEvent: NSAppleEventDescriptor) {
        if let urlString = event.forKeyword(AEKeyword(keyDirectObject))?.stringValue {
            let url = URL(string: urlString)
            guard url != nil, let scheme = url!.scheme else {
                //some error
                return
            }
            if scheme.caseInsensitiveCompare("yourSchemeUrl") == .orderedSame {
                //your code
            }
        }
    }
Related