我想使用ASWebAuthenticationSession
针对OAuth API进行身份验证,但是它似乎无法从SwiftUI使用。
这就是我想要的:
struct ContentView: View: ASWebAuthenticationPresentationContextProviding {
var body: some View {
NavigationView {
VStack {
Button("Hello World", {
// Run oauth flow
}
}
}
.navigationBarTitle(Text("Greed of Savin"))
.navigationViewStyle(StackNavigationViewStyle())
}
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return BungieApi.sharedInstance.presentationAnchor ?? ASPresentationAnchor()
}
}
}
它需要采用与SwiftUI的视图不兼容的协议ASWebAuthenticationPresentationContextProviding
。
我可以通过重定向到ViewController来解决这个问题,该ViewController随后可以提供ASWebAuthenticationPresentationContextProviding
,但这又增加了一个额外的视图/导航步骤。
有什么方法可以通过SwiftUI使用ASWebAuthenticationSession
而不放入ViewController中吗?
答案 0 :(得分:0)
我分三个部分解决了这个问题:
首先,在SceneDelegate.swift
中进行设置期间,在全局对象中捕获窗口:
var globalPresentationAnchor: ASPresentationAnchor? = nil
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// ...
globalPresentationAnchor = window
}
}
然后,创建一个小的ViewController,以将窗口对象提供给使用ASWebAuthenticationSession
的人:
class ShimViewController: UIViewController, ASWebAuthenticationPresentationContextProviding
{
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
// Perhaps I don't need the window object at all, and can just use:
// return ASPresentationAnchor()
return globalPresentationAnchor ?? ASPresentationAnchor()
}
}
最后,调用身份验证API,将ShimViewController作为演示者。
let session = ASWebAuthenticationSession(/**/)
session.presentationContextProvider = ShimViewController()
session.start()
答案 1 :(得分:0)
使用 BetterSafariView ,可以使用ASWebAuthenticationSession
而不用钩住SceneDelegate
在SwiftUI中。
import SwiftUI
import BetterSafariView
struct ContentView: View {
@State private var startingWebAuthenticationSession = false
var body: some View {
Button("Start WebAuthenticationSession") {
self.startingWebAuthenticationSession = true
}
.webAuthenticationSession(isPresented: $startingWebAuthenticationSession) {
WebAuthenticationSession(
url: URL(string: "https://github.com/login/oauth/authorize?client_id=\(clientID)")!,
callbackURLScheme: "myapp"
) { callbackURL, error in
print(callbackURL, error)
}
}
}
}