我正在使用FileProvider library在FTP服务器上查找文件,并使用Swift 5的基本功能在设备的“文档”文件夹中查找文件:
func lookForFiles() { //runs on a background thread
var ftpExists = false
var localExists = false
let ftpFile:FileObject = lookForFTPFile()
let localFile:FileObject = lookForLocalFile()
//Compare,... files
}
func lookForFTPFile() -> FileObject? {
var found:FileObject?
ftpProvider?.contentsOfDirectory(path: mypath, completionHandler: { (contents, error) in
//Look for ftp file
}) //This is run in an async task according to documentation
return found
}
由于“ contentsOfDirectory”中的任务,这当然总是返回“ nil”(我也无法从内部返回文件)。
问题::如何在返回结果之前等待lookForFTPFile
完成(这可能为零,因为它根本没找到任何东西),而没有设置计时器?
我希望不要弄混该库如何设置其异步工作。
类似
var waitingbool = false
var found:FileObject?
func lookForFiles() { //runs on a background thread
//Rest of code
lookForFTPFile()
while !waitingbool {}
//Use "found"
}
func lookForFTPFile() {
ftpProvider?.contentsOfDirectory(path: mypath, completionHandler: { (contents, error) in
//Look for ftp file and save result in "found"
self.waitingbool = true
})
}
看起来可能可行,但同时似乎违反了许多不成文的规则。
答案 0 :(得分:2)
每个没有在Swift中完成异步的人都会遇到相同的问题。如果您从不带闭包的方法中返回一个值(如您所做的那样),则它必须返回同步。正如您所注意到的,由于您的完成处理程序将异步运行,因此我们遇到了问题。您应该使用完成处理程序块从异步方法返回一个值。
我将按照以下方式重写您的方法:
product_credit
呼叫方:
func find(content: @escaping (FileObject?) -> ()) {
var found: FileObject?
// init the found variabel somewhere
ftpProvider?.contentsOfDirectory(path: mypath, completionHandler: { (contents, error) in
// You are in a closure completion block here also!
// send a callback to our waiting function...
content(contents)
})
// If ftpProvider is nil, please call the content completion handler block with nil also!
}