Как работать со схемой URL по умолчанию
Я хочу создать поддержку URI (или схемы URL) в моем приложении.
Я делаю LSSetDefaultHandlerForURLScheme()
в моем + (void)initialize
и я установил конкретные схемы URL также в моем info.plist
, Так что у меня есть схемы URL без Apple Script
или же Apple Events
,
Когда я звоню myScheme:
в моем любимом браузере система активирует мое приложение.
Проблема в том, как обращаться со схемами, когда они вызываются. Или лучше сказать: как я могу определить, что должно делать мое приложение, когда myScheme:
называется.
Есть ли какой-то особый метод, который я должен внедрить, или я должен где-нибудь его зарегистрировать?
4 ответа
Поскольку вы упоминаете 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:
- Документация
Все кредиты должны идти в Weichsel и KCH
Я просто добавляю код 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)")
}
}
Проблема в том, как обращаться со схемами, когда они вызываются.
Вот тут и появляются события Apple. Когда Launch Services хочет, чтобы ваше приложение открыло URL, оно отправляет ваше приложение kInternetEventClass
/kAEGetURL
событие.
Руководство по написанию сценариев Cocoa использует эту задачу в качестве примера установки обработчика событий.
Я просто добавляю немного другую версию кода 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)")
}
}
Вы можете определить команду "get URL" в терминологии сценариев SDEF и реализовать соответствующий метод. Например, 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 { … }