通过URL方案打开Cocoa App

时间:2017-09-06 02:22:30

标签: swift macos cocoa

我的问题与this question完全相同,但是它已经有一段时间没有更新了,而且自从被问到这个问题以来,Swift已经发生了很大的变化,因此答案可能需要刷新。我想要做的就是捕获用于打开我的cocoa应用程序的URL,但代码永远不会在我的处理函数中执行。当我通过自定义URL方案启动我的应用程序时,在Console.app中抛出错误。以下是错误:

-[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.

我的骨头应用程序:

创建一个名为MyApp的新Cocoa应用程序。在信息> URL类型,在标识符字段中输入我的应用程序包标识符,在URL方案字段中输入blue(例如)。将以下两个函数添加到AppDelegate类:

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!")
}

构建并运行我的应用。退出它,然后在地址栏中的Safari类型blue://whatever中点击并返回。该应用程序打开,但NSLog没有显示在Console.app中,而是我得到了上面提到的错误。我很想被困在如何解析网址,但我甚至无法进入那个部分。我正在运行Xcode 8.3.3(8E3004b)和Swift 3.1。你们都得到和我一样的结果吗?我调用处理函数是错误的吗?

2 个答案:

答案 0 :(得分:3)

尝试使用#selector(AppDelegate.handleGetURLEvent(event:replyEvent:))替换#selector-[MyApp.AppDelegate handleGetURLEvent:replyEvent:]: unrecognized selector sent to instance 0x60c0000039b0 宏将在编译时验证方法的存在,因此它应该在运行时使用正确的选择器。

作为旁白

handleGetURLEvent:replyEvent:

表示在AppDelegate上调用Selector(),但它没有响应此消息,这意味着选择器拼写错误或者发送到错误的对象。在这种情况下,可能是拼写错误的情况,因为#selector语法是Obj-C,因此很难知道Swift中的等价物是什么。这就是您应该使用datePicker.setYearRange(1950,2017);

的原因

答案 1 :(得分:2)

@Lucas Derraugh是一个天才 - 我全神贯注地寻找解决方案。谢谢!

Swift 4 Xcode上的一个附加功能促使我将@objc添加到函数中,所以我有:

  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.. 

    }