如何处理默认 URL 方案

发布于 2024-08-16 18:35:52 字数 423 浏览 20 评论 0原文

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

我在 + (void)initialize 中执行了 LSSetDefaultHandlerForURLScheme(),并在 info.plist 中设置了特定的 URL 方案。所以我有没有 Apple ScriptApple Events 的 URL 方案。

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

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

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

I want to build URI (or URL scheme) support in my app.

I do a LSSetDefaultHandlerForURLScheme() in my + (void)initialize and I setted the specific URL schemes also in my info.plist. So I have URL schemes without Apple Script or Apple Events.

When I call myScheme: in my favorite browser the system activates my app.

The problem is, how to handle the schemes when they are called. Or better said: How can I define what my app should do, when myScheme: is called.

Is there a special method that I have to implement or do I have to register one somewhere?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我家小可爱 2024-08-23 18:35:52

正如您提到的 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 : - 文档

As you are mentioning AppleScript, I suppose you are working on Mac OS X.

A simple way to register and use a custom URL scheme is to define the scheme in your .plist:

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

To register the scheme, put this in your AppDelegate's initialization:

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

Whenever your application gets activated via URL scheme, the defined selector gets called.

A stub for the event-handling method, that shows how to get the URL string:

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

Apple's documentation: Installing a Get URL Handler

Update
I just noticed a problem for sandboxed apps that install the event handler in applicationDidFinishLaunching:. With enabled sandboxing, the handler method doesn't get called when the app is launched by clicking a URL that uses the custom scheme.
By installing the handler a bit earlier, in applicationWillFinishLaunching:, the method gets called as expected:

- (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);
}

On the iPhone, the easiest way to handle URL-scheme activation is, to implement UIApplicationDelegate's application:handleOpenURL: - Documentation

糖粟与秋泊 2024-08-23 18:35:52

所有积分均应归于 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)")
    }
}

All credits should go to weichsel and kch

I'm just adding swift(2.2/3.0) code for your convenience

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)")
    }
}
笨死的猪 2024-08-23 18:35:52

问题是,调用时如何处理这些方案。

这就是 Apple 事件的用武之地。当启动服务希望您的应用程序打开 URL 时,它会向您的应用程序发送一个 kInternetEventClass/kAEGetURL 事件。

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

The problem is, how to handle the schemes when they are called.

That's where the Apple Events come in. When Launch Services wants your app to open a URL, it sends your app a kInternetEventClass/kAEGetURL event.

The Cocoa Scripting Guide uses this very task as an example of installing an event handler.

云柯 2024-08-23 18:35:52

我只是添加稍微不同的 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)")
    }
}

I'm just adding slightly different Swift 4/5 version of the code:

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)")
    }
}
往日情怀 2024-08-23 18:35:52

您可以在脚本术语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 { … }

You can define the “get URL” command in a scripting terminology SDEF and implement the corresponding method. For example, Terminal’s SDEF contains the following command definition for handling URLs

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

and declares that the application responds to it:

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

The TTApplication class (a subclass of NSApplication) defines the method:

- (void)handleGetURLScriptCommand:(NSScriptCommand *)command { … }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文