5

我创建了一个从任何 OSX 浏览器中的自定义 url 启动的应用程序。通过将标准 CFBundleURLName 条目添加到应用程序的 plist 中,这工作得很好。

我的应用程序通过解析自定义 url 上的一些参数然后对它们做出反应来工作。

因此,例如使用以下自定义 url:

foobar://param1/param2/param3

在浏览器中单击上面的 url 时,OSX 将启动我的应用程序并将实际的自定义 url 本身作为第一个参数传递给应用程序。因此,在应用程序中,我可以读取第一个参数并获取打开应用程序的 url,并将其解析为我需要的参数。

这在 OSX 10.5-10.8 中运行良好,但在 10.9 Mavericks 中似乎略有不同。也就是说,如果应用程序尚未运行,它仍会启动应用程序,但不会将自定义 url 作为第一个参数传递 - 所以应用程序认为它只是由用户手动启动(例如从启动板选择)而不是直接从浏览器。

奇怪的是,如果应用程序已经打开,那么单击自定义 url 确实会将 url 字符串作为第一个参数发送到应用程序,并且应用程序中的功能会按预期发生。

我已经使用我的应用程序的新旧版本在 10.6->10.9 中对此进行了测试,并且都表现出相同的行为。在 10.9 Mavericks 之前的版本首次启动时一切正常,但在 10.9 中,它们不会将 url 作为第一个 arg 传递,而是在已经运行后进行第二次单击。

如果有人能对此有所了解,我将不胜感激。

4

1 回答 1

1

您在哪里设置 URL 处理程序?它需要尽早发生。如果您当前有它applicationDidFinishLaunching,请尝试将其移至applicationWillFinishLaunching.

例如,以下内容适用于我并在启动时记录 URL,即使在我在 Safari 中打开 URL 之前应用程序未运行也是如此。当我将 WillFinishLaunching 更改为 DidFinishLaunching 时,我看到了您所描述的行为。

@implementation AppDelegate

- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
    NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}

- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
    NSAppleEventDescriptor *obj = [event descriptorForKeyword:keyDirectObject];
    DescType type = [obj descriptorType];
    if (type == typeChar) {
        NSData *data = [obj data];
        if (data) {
            NSString *urlString = [[NSString  alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSURL *url = [NSURL URLWithString:urlString];
            NSLog(@"url: %@", url);
        }
    }
}

@end
于 2013-12-10T23:54:16.940 回答