cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to learn some quick and useful tips to make your day easier? Check out how Calvin uses Replay to get feedback from other teams at Dropbox here.

Discuss Dropbox Developer & API

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

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

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

Chetral
Explorer | Level 4
Go to solution

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

1 Accepted Solution

Accepted Solutions

Greg-DB
Dropbox Staff
Go to solution

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.

View solution in original post

2 Replies 2

Greg-DB
Dropbox Staff
Go to solution

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
Explorer | Level 4
Go to solution

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

You're the best 😉

 

Marco "Chetral" Pirola

Need more support?