如何在 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。

我希望有人会觉得这有用。