Подтвердить что ты не робот

Как обращаться со схемой URL по умолчанию

Я хочу создать поддержку URI (или схемы URL) в своем приложении.

Я делаю LSSetDefaultHandlerForURLScheme() в моем + (void)initialize, и я установил конкретные схемы URL также в моем info.plist. Поэтому у меня есть схемы URL без Apple Script или Apple Events.

Когда я вызываю myScheme: в моем любимом браузере, система активирует мое приложение.

Проблема в том, как обрабатывать схемы при их вызове. Или лучше сказал: как я могу определить, что должно делать мое приложение, когда вызывается myScheme:.

Есть ли специальный метод, который я должен реализовать или мне нужно зарегистрировать где-нибудь?

4b9b3361

Ответ 1

Как вы уже упоминали 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: Установка обработчика Get Get

Обновление Я просто заметил проблему для изолированных приложений, которые устанавливают обработчик событий в 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: - Documentation

Ответ 2

Все кредиты должны идти в weichsel и kch

Я просто добавляю быстрый (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)")
    }
}

Ответ 3

Проблема в том, как обрабатывать схемы при их вызове.

Что происходит с событиями Apple. Когда Launch Services хочет, чтобы ваше приложение открывало URL-адрес, оно отправляет ваше приложение в событие kInternetEventClass/kAEGetURL.

В Cocoa Scripting Guide используется эта самая задача в качестве примера установки обработчика событий.

Ответ 4

Вы можете определить команду "получить 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 top-level scripting object.">
    <cocoa class="TTApplication"/>
    <responds-to command="get URL">
        <cocoa method="handleGetURLScriptCommand:" />
    </responds-to>
</class>

Класс TTApplication (подкласс NSApplication) определяет метод:

- (void)handleGetURLScriptCommand:(NSScriptCommand *)command { … }

Ответ 5

Я просто добавляю немного другую версию кода 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)")
    }
}