26

我想在我的应用程序中构建 URI(或 URL 方案)支持。

LSSetDefaultHandlerForURLScheme()在我的中做了一个,我+ (void)initialize也在我的info.plist. 所以我有没有Apple Scriptor的 URL 方案Apple Events

当我myScheme:在我最喜欢的浏览器中调用时,系统会激活我的应用程序。

问题是,当它们被调用时如何处理它们。或者更好地说:我如何定义我的应用程序应该做什么,什么时候myScheme:被调用。

是否有我必须实施的特殊方法,或者我必须在某处注册一个?

4

5 回答 5

76

当您提到 AppleScript 时,我想您正在使用 Mac OS X。

注册和使用自定义 URL 方案的一种简单方法是在 .plist 中定义方案:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>URLHandlerTestApp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>urlHandlerTestApp</string>
        </array>
    </dict>
</array>

要注册方案,请将其放入 AppDelegate 的初始化中:

[[NSAppleEventManager sharedAppleEventManager]
    setEventHandler:self
        andSelector:@selector(handleURLEvent:withReplyEvent:)
      forEventClass:kInternetEventClass
         andEventID:kAEGetURL];

每当您的应用程序通过 URL 方案激活时,都会调用定义的选择器。

事件处理方法的存根,显示如何获取 URL 字符串:

- (void)handleURLEvent:(NSAppleEventDescriptor*)event
        withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]
                        stringValue];
    NSLog(@"%@", url);
}

Apple 的文档:安装获取 URL 处理程序

更新 我刚刚注意到将事件处理程序安装在applicationDidFinishLaunching:. 启用沙盒后,通过单击使用自定义方案的 URL 启动应用程序时,不会调用处理程序方法。通过稍早安装处理程序,在 中applicationWillFinishLaunching:,该方法按预期调用:

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

- (void)handleURLEvent:(NSAppleEventDescriptor*)event
        withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]
                        stringValue];
    NSLog(@"%@", url);
}

在 iPhone 上,处理 URL 方案激活的最简单方法是实现 UIApplicationDelegate 的application:handleOpenURL:-文档

于 2010-01-02T10:15:22.990 回答
9

所有学分都应归weichselkch所有

为了您的方便,我只是添加了 swift(2.2/3.0) 代码

func applicationWillFinishLaunching(_ notification: Notification) {
    NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleGetURL(event:reply:)), forEventClass: UInt32(kInternetEventClass), andEventID: UInt32(kAEGetURL) )
}

@objc func handleGetURL(event: NSAppleEventDescriptor, reply:NSAppleEventDescriptor) {
    if let urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue {
        print("got urlString \(urlString)")
    }
}
于 2016-06-28T16:25:30.917 回答
6

问题是,当它们被调用时如何处理它们。

这就是 Apple 事件的用武之地。当 Launch Services 希望您的应用打开 URL 时,它会向您的应用发送kInternetEventClass/kAEGetURL事件。

Cocoa 脚本指南使用这个任务作为安装事件处理程序的示例

于 2010-01-02T10:16:07.967 回答
4

我只是添加了稍微不同的 Swift 4/5 版本的代码:

func applicationWillFinishLaunching(_ notification: Notification) {
    NSAppleEventManager
        .shared()
        .setEventHandler(
            self,
            andSelector: #selector(handleURL(event:reply:)),
            forEventClass: AEEventClass(kInternetEventClass),
            andEventID: AEEventID(kAEGetURL)
        )

}

@objc func handleURL(event: NSAppleEventDescriptor, reply: NSAppleEventDescriptor) {
    if let path = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue?.removingPercentEncoding {
        NSLog("Opened URL: \(path)")
    }
}
于 2019-09-03T11:16:02.330 回答
0

您可以在脚本术语 SDEF 中定义“get URL”命令并实现相应的方法。例如,终端的 SDEF 包含以下用于处理 URL 的命令定义

<command name="get URL" code="GURLGURL" description="Open a command an ssh, telnet, or x-man-page URL." hidden="yes">
    <direct-parameter type="text" description="The URL to open." />
</command>

并声明应用程序响应它:

<class name="application" code="capp" description="The application's top-level scripting object.">
    <cocoa class="TTApplication"/>
    <responds-to command="get URL">
        <cocoa method="handleGetURLScriptCommand:" />
    </responds-to>
</class>

TTApplication 类(NSApplication 的子类)定义了方法:

- (void)handleGetURLScriptCommand:(NSScriptCommand *)command { … }
于 2013-12-03T06:44:52.717 回答