如何在 SwiftUI 项目中使用 SwiftyDropbox API 进行身份验证?
How to authenticate using the SwiftyDropbox API in a SwiftUI project?
一段时间以来,我一直在尝试寻找在 SwiftUI 项目中使用他们的 SwiftyDropbox SDK 来验证 Dropbox 的解决方案,但这无济于事。
自述文件中提供的说明使用 AppDelegate 和 SceneDelegate。据我所知,后者在 SwiftUI 中是不可能的。我已经能够启动 OAuth2 Safari window,但 DropboxClientsManager.authorizedClient 始终为零。
终于想通了
按照 SwiftyDropbox 自述文件的说明设置 info.plist。
// <app_name>.swift
import SwiftUI
import SwiftyDropbox
@main
struct DropboxTestApp: App {
init() {
DropboxClientsManager.setupWithAppKey("<app key>")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// ContentView.swift
import SwiftUI
import SwiftyDropbox
struct ContentView: View {
@State var isShown = false
var body: some View {
VStack {
Button(action: {
self.isShown.toggle()
}) {
Text("Login to Dropbox")
}
DropboxView(isShown: $isShown)
Button {
if let client = DropboxClientsManager.authorizedClient {
print("successful login")
} else {
print("Error")
}
} label: {
Text("Test Login")
}
}
.onOpenURL { url in
let oauthCompletion: DropboxOAuthCompletion = {
if let authResult = [=11=] {
switch authResult {
case .success:
print("Success! User is logged into DropboxClientsManager.")
case .cancel:
print("Authorization flow was manually canceled by user!")
case .error(_, let description):
print("Error: \(String(describing: description))")
}
}
}
DropboxClientsManager.handleRedirectURL(url, completion: oauthCompletion)
}
}
}
struct DropboxView: UIViewControllerRepresentable {
typealias UIViewControllerType = UIViewController
@Binding var isShown : Bool
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
if isShown {
let scopeRequest = ScopeRequest(scopeType: .user, scopes: ["account_info.read", "files.metadata.write", "files.metadata.read", "files.content.write", "files.content.read"], includeGrantedScopes: false)
DropboxClientsManager.authorizeFromControllerV2(
UIApplication.shared,
controller: uiViewController,
loadingStatusDelegate: nil,
openURL: { (url: URL) -> Void in UIApplication.shared.open(url, options: [:], completionHandler: nil) },
scopeRequest: scopeRequest)
}
}
func makeUIViewController(context _: Self.Context) -> UIViewController {
return UIViewController()
}
}
您不需要创建 AppDelegate。
我希望有人会觉得这有用。
一段时间以来,我一直在尝试寻找在 SwiftUI 项目中使用他们的 SwiftyDropbox SDK 来验证 Dropbox 的解决方案,但这无济于事。
自述文件中提供的说明使用 AppDelegate 和 SceneDelegate。据我所知,后者在 SwiftUI 中是不可能的。我已经能够启动 OAuth2 Safari window,但 DropboxClientsManager.authorizedClient 始终为零。
终于想通了
按照 SwiftyDropbox 自述文件的说明设置 info.plist。
// <app_name>.swift
import SwiftUI
import SwiftyDropbox
@main
struct DropboxTestApp: App {
init() {
DropboxClientsManager.setupWithAppKey("<app key>")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// ContentView.swift
import SwiftUI
import SwiftyDropbox
struct ContentView: View {
@State var isShown = false
var body: some View {
VStack {
Button(action: {
self.isShown.toggle()
}) {
Text("Login to Dropbox")
}
DropboxView(isShown: $isShown)
Button {
if let client = DropboxClientsManager.authorizedClient {
print("successful login")
} else {
print("Error")
}
} label: {
Text("Test Login")
}
}
.onOpenURL { url in
let oauthCompletion: DropboxOAuthCompletion = {
if let authResult = [=11=] {
switch authResult {
case .success:
print("Success! User is logged into DropboxClientsManager.")
case .cancel:
print("Authorization flow was manually canceled by user!")
case .error(_, let description):
print("Error: \(String(describing: description))")
}
}
}
DropboxClientsManager.handleRedirectURL(url, completion: oauthCompletion)
}
}
}
struct DropboxView: UIViewControllerRepresentable {
typealias UIViewControllerType = UIViewController
@Binding var isShown : Bool
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
if isShown {
let scopeRequest = ScopeRequest(scopeType: .user, scopes: ["account_info.read", "files.metadata.write", "files.metadata.read", "files.content.write", "files.content.read"], includeGrantedScopes: false)
DropboxClientsManager.authorizeFromControllerV2(
UIApplication.shared,
controller: uiViewController,
loadingStatusDelegate: nil,
openURL: { (url: URL) -> Void in UIApplication.shared.open(url, options: [:], completionHandler: nil) },
scopeRequest: scopeRequest)
}
}
func makeUIViewController(context _: Self.Context) -> UIViewController {
return UIViewController()
}
}
您不需要创建 AppDelegate。
我希望有人会觉得这有用。