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

Chetral's avatar
Chetral
Explorer | Level 4
6 years ago

Downloading a file, getting error in DropboxTransportClient.swift, line 200

Hi all,

I've checked the forum and didn't find an answer.

Overview: my app works with a SQLite db. I have an option to store the DB in DropBox (only store it, not working on it).

The user download the DB, I create a file "device name".usr to say to other users the DB is in use right now.

I've created this procedure (sorry, comments are in Italian):

    func copiaDB() {
        let databaseURL = try! FileManager.default
            .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("db.sqlite")
        let completeUrl = URL(fileURLWithPath: databaseURL.path)
        let destination: (URL, HTTPURLResponse) -> URL = { temporaryURL, response in
                return completeUrl
        }
        
        let semo = DispatchSemaphore.init(value: 0)
        let downQueue = OperationQueue.init()
        downQueue.maxConcurrentOperationCount = 1
        // operation 1
        downQueue.addOperation {

            // detach database o errore sqlite
                dbQueue = try? AppDatabase.openDatabase(atPath: "")
                // copio file
            self.client?.files.download(path: "/db.sqlite", overwrite: true, destination: destination)
        }
        // operation 2
        downQueue.addOperation {
            // avverto che qualcuno sta lavorando sul file
            
            let fileData = "Database in uso".data(using: String.Encoding.utf8, allowLossyConversion: false)!

            self.client?.files.upload(path: "/\(UIDevice.current.name).usr", input: fileData)
        }
        // operation 3
        downQueue.addOperation {
            semo.wait()
            dbQueue = try? AppDatabase.openDatabase(atPath: databaseURL.path)
        }
    }

 It work's fine, detach the DB, download it, create the usr file, attach the DB to queue so I can work on it locally.

Here there is a little problem, not reguaridng DropBox. I need a way to advise user the download is completed, but i can't create an alert or change a label text because the download is async with the main queue.

I need the procedure to work with OperationQueue because

dbQueue = try? AppDatabase.openDatabase(atPath: databaseURL.path)

needs to be exeguted after the download is finished, or i risk to compromise the db.

 

Then I created the procedure to check if the db is available in DropBox: 

   

    func checkDB() {
        
        client?.files.search(path: "", query: ".usr", mode: .filename).response {
            response, error in
            if let response = response {
                if response.matches.count == 0 {
                    self.copiaDB()
                } else {
                    self.inUso(tipo: (response.matches.first?.metadata.name)!)
                }
            } else if let _ = error {
                
            }
        }
    }

self.inUso simply create an alert saying the device name is using the DB. This works, but, calling the first procedure copiaDB() I now got this error:

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/marcopirola/Desktop/Progetto Swift/Gestione Affitti/SwiftyDropbox/Source/SwiftyDropbox/Shared/Handwritten/DropboxTransportClient.swift, line 200

2019-11-10 11:10:02.238294+0100 Gestione Affitti[11658:6548246] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/marcopirola/Desktop/Progetto Swift/Gestione Affitti/SwiftyDropbox/Source/SwiftyDropbox/Shared/Handwritten/DropboxTransportClient.swift, line 200

 I tried to debug it, it actually download the db and create the .usr file, but then somehow it recalls the download procedure with a nil command string.

I removed checkDB() from the procedure calling directly copiaDB() and it works again. Any idea?

Thanks, Marco "Chetral" Pirola

  • It looks like the issue is that the SDK expects a 'response' handler on the 'files.download' call, but you're not supplying one. 

    I'll ask the team to fix this up to fail gracefully in this case, but as a workaround (and as a best practice in general), you should add a 'response' handler, e.g., as shown here:

    https://github.com/dropbox/SwiftyDropbox#download-style-request

    Also, I recommend doing so for all of your calls so you can add some error handling. Otherwise, you won't know if/why a call failed.

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

    It looks like the issue is that the SDK expects a 'response' handler on the 'files.download' call, but you're not supplying one. 

    I'll ask the team to fix this up to fail gracefully in this case, but as a workaround (and as a best practice in general), you should add a 'response' handler, e.g., as shown here:

    https://github.com/dropbox/SwiftyDropbox#download-style-request

    Also, I recommend doing so for all of your calls so you can add some error handling. Otherwise, you won't know if/why a call failed.

    • Chetral's avatar
      Chetral
      Explorer | Level 4

      Thanks Greg, I added response and error handling and now it works again!!!

      You're the best ;)

       

      Marco "Chetral" Pirola