You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on what’s changed, what’s staying the same and what you can expect from the Dropbox Community overall.

Forum Discussion

VyacheslavB's avatar
VyacheslavB
Helpful | Level 5
5 years ago

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

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.

 

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    [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's avatar
      VyacheslavB
      Helpful | Level 5

      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's avatar
        Greg-DB
        Icon for Dropbox Staff rankDropbox Staff

        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.