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