[SOLVED] Solution to authenticating SwiftyDropbox in a SwiftUI project


For some time I have been trying to find a solution to authenticating Dropbox using their SwiftyDropbox SDK in a SwiftUI project, but this was to no avail.

The instructions provided in the readme use an AppDelegate and and SceneDelegate. The latter of which from what I understand is not possible with SwiftUI. I have been able to get the OAuth2 Safari window to launch, but DropboxClientsManager.authorizedClient is always nil.


Finally, I figured it.

Setup info.plist as the SwiftyDropbox readme instructs.

// <app_name>.swift

import SwiftUI
import SwiftyDropbox

struct DropboxTestApp: App {

    init() {
        DropboxClientsManager.setupWithAppKey("<app key>")
    var body: some Scene {
        WindowGroup {
// ContentView.swift

import SwiftUI
import SwiftyDropbox

struct ContentView: View {
    @State var isShown = false
    var body: some View {
        VStack {
            Button(action: {
            }) {
                Text("Login to Dropbox")

            DropboxView(isShown: $isShown)
            Button {
                if let client = DropboxClientsManager.authorizedClient {
                    print("successful login")
                } else {
            } label: {
                Text("Test Login")
        .onOpenURL { url in
            let oauthCompletion: DropboxOAuthCompletion = {
                if let authResult = $0 {
                    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)
                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()

You don’t need to create an AppDelegate.

I hope that someone may find this useful.

Answered By – Michael C

Answer Checked By – Gilberto Lyons (BugsFixing Admin)

Leave a Reply

Your email address will not be published.