我爸爸很生气,当他单击电子邮件超链接时,OSX 会尝试打开他从未使用过也不想学习的 Mail。他希望它只打开一个浏览器窗口到他的 ISP 提供的电子邮件服务 (bleh)。
我正在尝试编写一个基本上处理该交互的程序,但我无法弄清楚超链接中的电子邮件地址是如何传递给应用程序的。本质上...当我单击 foo@example.com 的 mailto 超链接时,操作系统如何告诉 Mail.app(或任何默认客户端)撰写新电子邮件到 foo@example.com?
首先,Mail.app 通过在其 Info.plist 文件中包含以下内容,被动地告诉 Launch Services 它处理“mailto” URL 方案:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Email Address URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mailto</string>
</array>
<key>LSIsAppleDefaultForScheme</key>
<true/>
</dict>
...
</array>
kInternetEventClass
接下来,它为/ kAEGetURL
Apple 事件设置一个处理程序。在 Cocoa 中,这看起来像:
NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
您可以像这样实现处理程序方法:
- (BOOL)handleGetURLEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
{
NSAppleEventDescriptor* directObjectDescriptor = [event paramDescriptorForKeyword:keyDirectObject];
NSString* urlString = [directObjectDescriptor stringValue];
NSURL* url = [NSURL URLWithString:urlString];
// ... do something with url ...
}
对于“mailto” URL,大部分解析行为NSURL
无效,因为 URL 不符合 RFC 1808(资源说明符不以“//”开头)。您实际上只能使用该-resourceSpecifier
方法获取方案(mailto)和资源说明符。某些 mailto URL 可能具有类似查询的语法,例如“?subject=Some%20subject%20text”,但NSURL
不会帮助您将其分开。因此,您需要手动执行此操作。(您可以考虑通过在资源说明符的前面注入“//”并对其进行NSURL
解析来构造一个虚假的 URL。)