cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to know what we learned at IBC? Check out our learnings on media, remote working and more right here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I have a problem with connecting Dropbox API to my iOS app with Swift 5

I have a problem with connecting Dropbox API to my iOS app with Swift 5

VyacheslavB
Helpful | Level 5
Go to solution

Dropbox API documentation is in front of my eyes, I do everything as it is written there step by step. But in some of the methods that are indicated there are errors and I do not know what to replace the entities that are indicated there. I can log in, but I cannot get the token, error instead: "-canOpenURL: failed for URL: "dbapi-2://1/connect" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"

 

import SwiftyDropbox

 

class AppDelegate:... {
   func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
   //error Use of undeclared type 'DropboxOAuthCompletion'
      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)
   return true
   }
}

 

import SwiftyDropbox

 

class ViewController:... {
   func openDropboxAutorization() {
      // Legacy authorization flow that grants a long-lived token.
      DropboxClientsManager.authorizeFromController(UIApplication.shared,
      controller: self,
      openURL: { (url: URL) -> Void in
      UIApplication.shared.open(url, options: [:], completionHandler: nil)
      })

      //New: OAuth 2 code flow with PKCE that grants a short-lived token with scopes.
      //error Use of unresolved identifier 'ScopeRequest'
      let scopeRequest = ScopeRequest(scopeType: .user, scopes: ["account_info.read"], includeGrantedScopes: false)
      DropboxClientsManager.authorizeFromControllerV2(
      UIApplication.shared,
      controller: self,
      loadingStatusDelegate: nil,
      openURL: { (url: URL) -> Void in UIApplication.shared.openURL(url) },
      scopeRequest: scopeRequest
      )
   }
}


Both of these methods are copied from the DropboxAppi documentation, but they don't work and I can't find the right solution.

 

1 Accepted Solution

Accepted Solutions

Greg-DB
Dropbox Staff
Go to solution

You can manage your app's development user limit from the app's page on the App Console:

 

https://www.dropbox.com/developers/apps

 

You can use enable more user accounts to connect to your app by clicking the "Enable additional users" button, to avoid this error for now, or when ready, you can apply for production using the "Apply for production" button. 

 

You can find more information on how this works here:

 

https://www.dropbox.com/developers/reference/developer-guide#production-approval

View solution in original post

9 Replies 9

Greg-DB
Dropbox Staff
Go to solution

[Cross-linking for reference: https://stackoverflow.com/questions/63409444/how-to-connect-dropbox-api-to-ios-app-with-swift-5 ]

 

For the "Use of undeclared type 'DropboxOAuthCompletion'" and "Use of unresolved identifier 'ScopeRequest'" errors, it sounds like you probably just have an older version of SwiftyDropbox installed, from before those new types were defined. Specifically, you'll need at least v6.0.0 (currently the latest version). If you're using Cocoapods, try running `pod update`.

 

Those "-10814" errors can be ignored. They just indicate that the official Dropbox iOS app isn't installed. The official Dropbox iOS app would be used for the authorization flow, if it's installed. If it's not, the SDK will just fall back to using the web site instead.

 

Also, the "Begin the authorization flow" documentation includes an example that shows both the old (`authorizeFromController`)
and new (`authorizeFromControllerV2`) methods for starting the authorization flow. You're using both, but in actual use you should only use one of them. The new one, `authorizeFromControllerV2`, is recommended, so you should remove the old one, `authorizeFromController`.

 

Finally, if you get to the authorization page and "Allow" the app, but don't then receive the result in your app, it may be because your app uses "scenes" but isn't configured to receive the result via scenes. In that case, add the following to your scene delegate:

import SwiftyDropbox
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        if let url = URLContexts.first?.url {
            
            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)
            
        }
    }

VyacheslavB
Helpful | Level 5
Go to solution

Thank you, your advice helped me! Now when I press Accept, it brings me back to my View. And if I press my button again to go to the Dropbox, then the View appears again with the question Accept or Cancel. Is that how it should be? 

Greg-DB
Dropbox Staff
Go to solution

No, you only need to process the app authorization flow once per user (unless they disconnect your app from Dropbox and want to reconnect it again).

 

Once they authorize your app, and your app receives the result via the "Handle redirect back into SDK" step, you shouldn't call authorizeFromController[V2] again. You'll likely want to remove that button from your UI at that point and replace it with some sort of "connected" state to show the user that they've successfully connected the app to the Dropbox. (You can also offer a way for them to disconnect it and show that button again.)

 

You can check authorizedClient to see that the user is connected and that you have a client to call Dropbox with, and then use it to make API calls, as shown in the "Try some API requests" section.

VyacheslavB
Helpful | Level 5
Go to solution

Thanks for your support.
After the user has successfully logged in, I want to display a list of their files on the screen. What's the best way to do this? Should I display it in my View, or does Dropbox provide some kind of web interface as when authorizing?

Greg-DB
Dropbox Staff
Go to solution

After authorization, Dropbox does not provide UI, so you should make the necessary API call(s) and display the results in your app's UI as needed.

 

For listing files and folders, you should use listFolder and listFolderContinue.

VyacheslavB
Helpful | Level 5
Go to solution

There is one more question. There is one more question. I get an error when I log out and then re-enter the Dropbox. What is the reason for this?

Screen Shot 2020-08-18 at 15.56.46.png

For logging out I use DropboxClientsManager.unlinkClients()

Greg-DB
Dropbox Staff
Go to solution

I see you're getting the error "Unexpectedly found nil while unwrapping an Optional value" for that line, presumably regarding the "client" variable. This screenshot doesn't show where that variable would be set or unset, but this error indicates that its value is currently nil. Accordingly, attempting to force unwrap it as you are doing fails. You should instead check it is not nil before accessing it.

 

This isn't specific to Dropbox code though. You can find more information about this in the Swift documentation, or elsewhere, such as this post on StackOverflow.

VyacheslavB
Helpful | Level 5
Go to solution

Thanks, I figured it out. I called the dropboxManager.fetchFiles () method when the user is not logged in.
There is another question, when I try to get the list of user's files the message appears

2020-08-19 12.48.56.jpg

Greg-DB
Dropbox Staff
Go to solution

You can manage your app's development user limit from the app's page on the App Console:

 

https://www.dropbox.com/developers/apps

 

You can use enable more user accounts to connect to your app by clicking the "Enable additional users" button, to avoid this error for now, or when ready, you can apply for production using the "Apply for production" button. 

 

You can find more information on how this works here:

 

https://www.dropbox.com/developers/reference/developer-guide#production-approval

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Greg-DB Dropbox Staff
  • User avatar
    VyacheslavB Helpful | Level 5
What do Dropbox user levels mean?