我正在开发与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应用。
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")
}
}
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")
}
}
答案 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将我推向正确的方向。
现在我有
func application(_ application: NSApplication, open urls: [URL])
(事实证明,这真的足够@Aaron Raimist所说的感谢您的帮助;希望这可以对其他人(或我未来的自我)有所帮助:-)