重定向的目的
我正在开发一个与思科的Webex Teams Api集成的应用程序 . 不幸的是,对于macOS,他们没有SDK(他们只有一个用于iOS),所以我试图用他们的Api类型“手动”进行身份验证 .
所以,我使用的是支持客户端ID的自定义URL来检索代码 . 调用此URL时,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
就我目前所知,似乎我需要在我的_45796中有一个额外的函数来处理回调 . 对于 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
-
Swift 4.2
-
Cocoa app
-
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")
}
}
1 回答
在Info.plist中,在
CFBundleURLSchemes
键下的数组中指定URL方案,而不指定://
后缀(ch.appfros.webexoauthwokflowprototype
而不是ch.appfros.webexoauthwokflowprototype://
) . 虽然连字符和点在技术上被允许作为该方案的一部分,并且总是在操作系统和接收方(在应用程序中)为我工作,但我可以模糊地记住,一些第三方Web浏览器使用连字符填充自定义方案,最终导致仅从字母中定义方案 .顺便说一句,Apple建议对
CFBundleURLName
使用反向DNS样式标识符(名称,而不是方案本身) .此外,
NSApplicationDelegate
协议中的application:openURLs:
似乎是macOS 10.13中的新功能 . 过去,自定义网址方案公开活动是通过AppleEvents提供的,到目前为止,这对我来说是完美无缺的 . 要执行此操作,请尽早为kInternetEventClass
/kAEGetURL
注册NSAppleEventManager
的事件处理程序,例如在applicationWillFinishLaunching
中 .从已知的工作实现(在Objective-C中),在app委托实现中: