完成后使用异步库的结果

时间:2019-05-27 11:41:18

标签: swift asynchronous

我正在使用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
    }) 
}

看起来可能可行,但同时似乎违反了许多不成文的规则。

1 个答案:

答案 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!
}