macos 如何处理默认 URL 方案
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1991072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle with a default URL scheme
提问by papr
I want to build URI (or URL scheme) support in my app.
我想在我的应用程序中构建 URI(或 URL 方案)支持。
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
.
我LSSetDefaultHandlerForURLScheme()
在 my 中做了一个,我+ (void)initialize
也在我的info.plist
. 所以我有没有Apple Script
或 的URL 方案Apple Events
。
When I call myScheme:
in my favorite browser the system activates my app.
当我调用myScheme:
我最喜欢的浏览器时,系统会激活我的应用程序。
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.
问题是,如何在调用时处理这些方案。或者更好地说:我如何定义我的应用程序应该做什么,何时myScheme:
被调用。
Is there a special method that I have to implement or do I have to register one somewhere?
是否有我必须实施的特殊方法,或者我必须在某处注册一个方法?
回答by Thomas Zoechling
As you are mentioning AppleScript, I suppose you are working on Mac OS X.
当您提到 AppleScript 时,我想您正在使用 Mac OS X。
A simple way to register and use a custom URL scheme is to define the scheme in your .plist:
注册和使用自定义 URL 方案的一种简单方法是在 .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:
要注册该方案,请将其放在 AppDelegate 的初始化中:
[[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.
每当您的应用程序通过 URL 方案激活时,就会调用定义的选择器。
A stub for the event-handling method, that shows how to get the URL string:
事件处理方法的存根,显示如何获取 URL 字符串:
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
NSString* url = [[event paramDescriptorForKeyword:keyDirectObject]
stringValue];
NSLog(@"%@", url);
}
Apple's documentation: Installing a Get URL Handler
Apple 的文档:安装获取 URL 处理程序
UpdateI 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:
更新我刚刚注意到在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);
}
On the iPhone, the easiest way to handle URL-scheme activation is, to implement UIApplicationDelegate's application:handleOpenURL:
- Documentation
在 iPhone 上,处理 URL-scheme 激活的最简单方法是实现 UIApplicationDelegate 的application:handleOpenURL:
-文档
回答by Laimis
All credits should go to weichseland kch
所有的学分应该去weichsel和KCH
I'm just adding swift(2.2/3.0) code for your convenience
为了您的方便,我只是添加了 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) )
}
func handleGetURL(event: NSAppleEventDescriptor, reply:NSAppleEventDescriptor) {
if let urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue {
print("got urlString \(urlString)")
}
}
回答by Peter Hosey
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.
这就是 Apple 事件的用武之地。当 Launch Services 想要您的应用程序打开一个 URL 时,它会向您的应用程序发送一个kInternetEventClass
/kAEGetURL
事件。
The Cocoa Scripting Guideuses this very task as an example of installing an event handler.
回答by Martin Pilch
I'm just adding slightly different Swift 4/5 version of the code:
我只是添加了稍微不同的 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)")
}
}
回答by Chris Page
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
您可以在脚本术语 SDEF 中定义“获取 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>
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:
TTApplication 类(NSApplication 的子类)定义了方法:
- (void)handleGetURLScriptCommand:(NSScriptCommand *)command { … }