自定义重定向URI到macOS应用程序不起作用

时间:2018-12-09 11:50:10

标签: xcode cocoa wkwebview cisco webex

重定向的目的

我正在开发与Cisco Webex Teams Api集成的应用程序。不幸的是,对于macOS,他们没有SDK(他们只有一个针对iOS的SDK),因此我尝试使用“手动”身份对其Api进行身份验证。

因此,我使用的是一个自定义URL,该URL具有备份的客户ID来检索代码。呼叫此URL时,Cisco的常规登录过程开始,要求用户使用其用户名登录并输入密码。成功登录后,Cisco的服务器会为您提供一个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应用。

环境

  • Xcode 10.1
  • 迅速4.2
  • 可可应用
  • Cisco Webex Teams与身份验证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 :(得分:2)

很抱歉将此作为答案发布,但是我没有足够的StackOverflow信誉来发表评论

回复此评论: Custom redirect URI to macOS app not working

我有完全相同的问题。对我来说,解决这个问题的方法,听起来很愚蠢,是清理build文件夹。之后,我的代码立即生效。

回复此评论: Custom redirect URI to macOS app not working

如果使用https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application而不是旧的方式(例如:https://github.com/gittower/custom-url-schemes)以现代方式进行注册,则根本不需要处理程序注册。

答案 1 :(得分:1)

在Info.plist的CFBundleURLSchemes键下的数组中,指定URL方案,不带后缀://ch.appfros.webexoauthwokflowprototype代替ch.appfros.webexoauthwokflowprototype://)。

顺便说一句,Apple建议为CFBundleURLName (名称,而不是方案本身)使用反向DNS样式标识符。

我已经建立了一个最小的测试项目: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并在项目的沙箱设置中启用传出连接)。

过去,我曾见过一些第三方浏览器在包含连字符和点的自定义方案上cho之以鼻。对于WKWebView和os中底层的自定义URL方案处理来说,这似乎没有问题。使用NSWorkspace方法和WKWebView进行测试时,no.half-bits而不是nohalfbits可以按预期工作。

答案 2 :(得分:0)

事实证明,沙箱确实是问题所在。禁用沙箱功能后-我的公司将成为内部帮助的小助手,没什么花哨的东西,对于任何商店来说肯定没有任何东西-它立即起作用。

如果需要,我将不得不研究实现NSAppTransportSecurity的方式-感谢@NoHalfBits将我推向正确的方向。

现在我有

  • 注册的自定义网址
  • 已禁用应用沙箱
  • 在我的AppDelegate中实现的
  • func application(_ application: NSApplication, open urls: [URL])(事实证明,这真的足够@Aaron Raimist所说的

感谢您的帮助;希望这可以对其他人(或我未来的自我)有所帮助:-)