Пользовательский URI перенаправления в приложение MacOS не работает - PullRequest
0 голосов
/ 09 декабря 2018

Цель перенаправления

Я работаю над приложением, которое интегрируется с Cisco Webex Teams Api.К сожалению, для macOS у них нет SDK (у них есть только один для iOS), поэтому я пытаюсь аутентифицироваться с их типом Api «вручную».

Итак, я использую пользовательский URL-адрес с резервной копией идентификатора клиента для получения кода.При вызове этого URL-адреса запускается обычная процедура входа в систему Cisco, в которой пользователю предлагается войти в систему со своим именем пользователя и паролем.После успешного входа в систему сервер Cisco предоставит вам URL-адрес, содержащий код, который затем необходим для продолжения.

Что я получил до сих пор

Пользовательский URL

Мой прототип в настоящее время просто состоит из кнопки, которая вызывает пользовательский URL для аутентификации.Чтобы получить этот URL, мне нужно было зарегистрировать свою интеграцию с Cisco здесь: https://developer.webex.com/my-apps

До сих пор, когда я нажимаю на мою кнопку, экземпляр WKWebView вступает во владение моим пользовательским URL:

https://api.ciscospark.com/v1/authorize?client_id=<**personalClientId**>&response_type=code&redirect_uri=<**BundleIdentifier**>3A%2F%2Fredirect&scope=spark%3Aall%20spark%3Akms&state=set_state_here

URI перенаправления

Итак, мой URI перенаправления в настоящее время ch.appfros.webexoauthwokflowprototype: // redirect ;Этот URI перенаправления зарегистрирован в Cisco в моей регистрационной форме интеграции.

Мне известно, что я должен поместить этот URI перенаправления в свое приложение, поэтому я сделал это, в результате соответствующий раздел info.plist выглядел следующим образом:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>response</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>ch.appfros.webexoauthwokflowprototype://</string>
        </array>
    </dict>
</array>

Подготовка AppDelegate

Насколько я понял, мне кажется, что мне нужна дополнительная функция в моем AppDelegate, который обрабатывает обратный вызов.Для cocoa это, похоже, метод func application(_ application: NSApplication, open urls: [URL]).

Насколько я понимаю, мне придется обрабатывать все перенаправления там.Мой AppDelegate в настоящее время выглядит следующим образом:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {



    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application)
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    func application(_ application: NSApplication, open urls: [URL]) {
        print("got answer")
    }

}

У меня проблема

Моя проблема в том, что при выполнении процедуры входа в систему появляется сообщение There is no application set to open the URL ch.appfros.webexoauthwokflowprototype://redirect?code=&state=loggedIn.

Итак, процесс аутентификации на стороне Cisco проходит успешно, и он предоставляет моей системе URL-адрес, который мой компьютер не знает, как обрабатывать ... Я даже вижу код, необходимый для получения доступа, в URL-адресечто возвращается, у меня просто нет их в моем заявлении, чтобы продолжить ...

Чего мне не хватает?

Совершенно очевидно, что я упускаю что-то важное здесь - япросто не знаю, что это такое, и исследование онлайн не поможет мне.Я мог бы найти кусочки здесь и там, но я все еще должен найти краткую инструкцию о том, что делать в моем случае для моего приложения MacOS.

Environment

  • Xcode 10.1
  • Swift 4.2
  • Приложение Cocoa
  • Интеграция команд Cisco Webex с URL-адресом аутентификации

Редактировать: изменения в AppDelegate

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {



    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application)
         NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    func application(_ application: NSApplication, open urls: [URL]) {
        print("got answer")
    }

    @objc
    func handleAppleEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
        print("got answer in event handler")
    }

}

Редактирование 2: обновление до AppDelegate (для отражения подсказок и подсказок от NoHalfBits)

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {



    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application)

    }

    func applicationWillFinishLaunching(_ notification: Notification) {
        NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(self.handleAppleEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    func application(_ application: NSApplication, open urls: [URL]) {
        print("got answer")
    }

    @objc
    func handleAppleEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
        print("got answer in event handler")
    }

}

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018

Извините за публикацию этого ответа, но у меня недостаточно репутации StackOverflow, чтобы написать комментарий comment

В ответ на этот комментарий: Пользовательский URI перенаправления на macOSприложение не работает

У меня была точно такая же проблема.Для меня, что исправило это, как бы глупо это не звучало, это очистить папку сборки.После этого мой код сразу заработал.

Ответ на этот комментарий: Не работает пользовательский URI перенаправления в приложение macOS

Вам не нужнорегистрация обработчика вообще, если вы делаете это современным способом с https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application вместо старого способа (пример: https://github.com/gittower/custom-url-schemes).

0 голосов
/ 14 декабря 2018

Оказывается, что песочница действительно была проблемой.После отключения Sandboxing - это будет маленький помощник в моей компании, ничего особенного и, конечно, ничего для любого магазина - это сработало сразу.

Если понадобится, мне придется взятьпосмотрите, как NSAppTransportSecurity потребуется для реализации - спасибо @NoHalfBits за то, что подтолкнули меня в правильном направлении.

Так что теперь у меня есть

  • зарегистрированный пользовательский URL
  • Песочница приложения отключена
  • func application(_ application: NSApplication, open urls: [URL]) реализована в моем AppDelegate (оказывается, этого действительно достаточно, поскольку @Aaron Raimist говорил

Спасибо за вашу помощь, надеюсь, что этоможет помочь кому-нибудь еще (или моему будущему себе) в будущем: -)

0 голосов
/ 10 декабря 2018

В Info.plist укажите схему URL в массиве под ключом CFBundleURLSchemes без суффикса :// (ch.appfros.webexoauthwokflowprototype вместо ch.appfros.webexoauthwokflowprototype://).

Кстати, Apple рекомендует использоватьидентификатор стиля обратного DNS для CFBundleURLName (имя, а не сама схема) .

Я настроил минимальный тестовый проект: Xcode 10.1, шаблон приложения Какао Swift.Часть Info.plist, определяющая пользовательскую схему:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>no.half.bits</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>nohalfbits</string>
        </array>
    </dict>
</array>

Делегат приложения просто:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    func application(_ application:NSApplication, open urls: [URL]) {
        print("openURLs:", urls)
    }
}

Это работает, как и ожидалось, при тестировании с небольшим инструментом командной строки:

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        NSURL* url = [NSURL URLWithString:@"nohalfbits://hello.world"];
        // is there app that handles the scheme, and where is it
        NSLog(@"appURL = %@", [NSWorkspace.sharedWorkspace URLForApplicationToOpenURL:url]);
        // actually open the url; the app should log this
        [NSWorkspace.sharedWorkspace openURL:url];
    }
    return 0;
}

Я также добавил WKWebView в проект и позволил ему загружать минимальную веб-страницу с сервера, просто содержащую ссылку с пользовательской схемой - как и ожидалось, нажатие на эту ссылку вызывает метод openURL с пользовательской схемой (пришлось добавить необходимый словарь NSAppTransportSecurity в Info.plist и включить исходящие соединения в настройках песочницы проекта).

В прошлом я видел, как некоторые сторонние браузеры блокировали пользовательские схемы, содержащиедефисы и точки.Для WKWebView и базовой пользовательской схемы URL в ОС это, похоже, не проблема;no.half-bits вместо nohalfbits работает должным образом при тестировании с помощью методов NSWorkspace и WKWebView.

...