Swift-阻止循环直到下载操作完成为止

Jud*_*020 0 foreach asynchronous swift alamofire

我目前正在尝试根据用户的游戏要求下载多个文件。我的目标是让它一次仅下载一个文件,并停止执行代码,直到该文件完成下载为止。

我的代码是一个JSON对象数组,每个对象都包含一个将它们下载到的路径以及该文件的URL。我正在遍历数组,并使用AlamoFire封闭地下载它们.downloadProgress

Alamofire.download(
json["url"].stringValue,
method: .get,
to: destination).downloadProgress(closure: { (Alamoprogress) in
info.stringValue = "Downloading: " + filename
progress.doubleValue = Alamoprogress.fractionCompleted * 100
}).response(completionHandler: { (DefaultDownloadResponse) in
})
Run Code Online (Sandbox Code Playgroud)

为了确保每次仅下载一个文件,我设置了DispatchQueue并将Alamofire请求移至同步操作中:

for jsonObject in jsonArray{
    queue.async {
    print("Started downloading " + filename)
    info.stringValue = "Downloading: " + filename
    info.placeholderString = "Downloading: " + filename
    info.isEnabled = true
    info.isHidden = false
    progress.isHidden = false
    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
        let documentsURL = filepath
        return (documentsURL, [.removePreviousFile])
    }
    Alamofire.download(
        json["url"].stringValue,
        method: .get,
        to: destination).downloadProgress(closure: { (Alamoprogress) in
                info.stringValue = "Downloading: " + filename
            progress.doubleValue = Alamoprogress.fractionCompleted * 100
        }).response(completionHandler: { (DefaultDownloadResponse) in
                            })
           }
}
Run Code Online (Sandbox Code Playgroud)

不过,调试日志将继续循环,同时下载文件,并将它们下载一个同步。这会导致info框和progress栏在下载时发疯,因为它一次下载了所有框和栏。我相信我已经建立了一个同步循环,但是它可能仍然是异步的,因为它一直在循环。

如何在此处阻止异步下载?

Cod*_*ent 6

使用信号量,以便一次只能下载一个:

let semaphore = DispatchSemaphore(value: 1)

for jsonObject in jsonArray {
    queue.async {
        semaphore.wait()

        print("Started downloading " + filename)
        info.stringValue = "Downloading: " + filename
        info.placeholderString = "Downloading: " + filename
        info.isEnabled = true
        info.isHidden = false
        progress.isHidden = false
        let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            let documentsURL = filepath
            return (documentsURL, [.removePreviousFile])
        }
        Alamofire.download( json["url"].stringValue, method: .get, to: destination)
            .downloadProgress{ Alamoprogress in
                info.stringValue = "Downloading: " + filename
                progress.doubleValue = Alamoprogress.fractionCompleted * 100
            }
            .response { response in
                semaphore.signal()
            }
    }
}
Run Code Online (Sandbox Code Playgroud)