Objective c 如何使用自定义URL方案将Get URL事件发送到正在运行的应用程序?

Objective c 如何使用自定义URL方案将Get URL事件发送到正在运行的应用程序?,objective-c,cocoa,Objective C,Cocoa,我的Cocoa应用程序需要处理Get URL事件。我想我正确地按照中的步骤修改了Info.plist并编写并注册了一个URL处理程序方法 问题: 我走的时候mytesturl://anything 在Safari中,当我的应用程序运行时,它会弹出一个窗口,询问我是否要打开我的应用程序。如果我说是的话,似乎什么也没有发生,除了一个图标在码头上出现了一瞬间。所以它可能试图启动我的应用程序的另一个实例,而不是向正在运行的实例发送消息 当我在Firefox中执行相同操作时,它会弹出一个窗口,要求我选择一

我的Cocoa应用程序需要处理Get URL事件。我想我正确地按照中的步骤修改了Info.plist并编写并注册了一个URL处理程序方法

问题:

  • 我走的时候mytesturl://anything 在Safari中,当我的应用程序运行时,它会弹出一个窗口,询问我是否要打开我的应用程序。如果我说是的话,似乎什么也没有发生,除了一个图标在码头上出现了一瞬间。所以它可能试图启动我的应用程序的另一个实例,而不是向正在运行的实例发送消息

  • 当我在Firefox中执行相同操作时,它会弹出一个窗口,要求我选择一个应用程序。那么定制URL协议不应该在所有浏览器中都能工作

  • Info.plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        ...
        <key>CFBundleURLTypes</key>
        <array>
            <dict>
                <key>CFBundleURLName</key>
                <string>My test URL</string>
                <key>CFBundleURLSchemes</key>
                <array>
                    <string>mytesturl</string>
                </array>
            </dict>
        </array>
         ...
    </dict>
    </plist>
    
    
    ...
    CbundleurlTypes
    CFBundleURLName
    我的测试URL
    循环流化床锅炉方案
    mytesturl
    ...
    
    源代码:

    #import <Cocoa/Cocoa.h>
    #include <stdio.h>
    
    @interface Test : NSObject
    {
    }
    - (void)test;
    - (void)handleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; 
    @end
    
    @implementation Test
    - (void)test
    {
        NSLog(@"Started..."); 
        char c; 
        scanf("%c", &c); 
    }
    
    - (void)handleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
    {
        NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]];
        NSLog(@"url = %@", url); 
    }
    @end
    
    int main(int argc, char *argv[])
    {
        Test *app=[[Test alloc] init];
        [[NSAppleEventManager sharedAppleEventManager] setEventHandler:app andSelector:@selector(handleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
    
        [app test];
    
        return 0;   
    }
    
    #导入
    #包括
    @接口测试:NSObject
    {
    }
    -(无效)试验;
    -(无效)handleEvent:(NSAppleEventDescriptor*)事件与replyEvent:(NSAppleEventDescriptor*)replyEvent;
    @结束
    @实施测试
    -(无效)试验
    {
    NSLog(@“已启动…”);
    字符c;
    scanf(“%c”、&c);
    }
    -(无效)handleEvent:(NSAppleEventDescriptor*)事件与replyEvent:(NSAppleEventDescriptor*)replyEvent
    {
    NSURL*url=[NSURL URLWithString:[[event ParamDescriptorWorkeryWord:keyDirectObject]stringValue]];
    NSLog(@“url=%@”,url);
    }
    @结束
    int main(int argc,char*argv[])
    {
    Test*app=[[Test alloc]init];
    [[NSAppleEventManager sharedAppleEventManager]setEventHandler:app和selector:@selector(handleEvent:withReplyEvent:)forEventClass:kInternetEventClass和Ventid:kAEGetURL];
    [应用程序测试];
    返回0;
    }
    
    NSAppleEventManager
    需要一个
    NSApplication
    实例才能运行

    尝试将
    Test
    作为
    NSApplication
    的子类,并将
    main
    更改为如下内容:

     id app = [NSApplication sharedApplication];
     [[NSAppleEventManager sharedAppleEventManager] setEventHandler:app andSelector:@selector(handleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
     [app run];
    

    正如您所指出的,这个应用程序缺少一个NSApplication,但我想澄清的是,任何对象都可以是事件处理程序,包括app委托。下面是一个小的演示项目: