Swift 完成和循环问题
Swift Completion & Loop Issue
正在尝试从三个 url 之一下载 PKG 文件。该逻辑基本上从每个下载 url 中找到一个下载的延迟,并将最终下载 url 设置为延迟最低的主机。
import Cocoa
import Alamofire
// Create my object via Struct
struct Package {
var latency: Double?
var name: String?
var statuscode: Int?
var download: Bool?
var downloadUrl: String?
}
// Download the package from the provided download url and return the object
func getPKG(pkgName: String, dpUrl: String, completion: @escaping (Package) -> (Package)) {
let url = URL(string: "\(dpUrl)\(pkgName)")
let parameters: Parameters = ["foo":"bar"]
Alamofire.download(url, method: .get, parameters: parameters, encoding: JSONEncoding.default, to: destination)
.downloadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
debugPrint("Download Progress...: \(progress.fractionCompleted)")
}
.validate(statusCode: 200..<399)
.response { response in
debugPrint(response.response!)
debugPrint(response.response!.statusCode)
debugPrint(response.timeline.latency)
let dlObject = Package(latency: response.timeline.latency, name: pkgName, statuscode: response.response?.statusCode, download: true, downloadUrl: dpUrl)
completion(dlObject)
}
}
var share_response = [String: Double]()
var package_sources: NSArray! = ["https://www.jss1.com/Share", "https://www.jss2.com/Share", "https://www.jss3.com/Share"]
let package_names: String = ["Dummy1.pkg", "Dummy2.pkg", "Dummy3.pkg"]
// Loop through the package sources and find the one with
// the lowest latency.
for share_url in package_sources {
getPKG(pkgName: "Dummy.pkg", dpUrl: share_url, completion: {
dlObject in
if dlObject.latency != nil {
share_response[share_url] = dlObject.latency
} else {
debugPrint("nothing yet")
}
return dlObject
})
}
let final_download_url = share_response.min { a, b in a.value < b.value }
// Here is where it breaks and responds with nil
for package in package_names {
let download_url = URL(string: final_download_url + package)
Download commands here...
}
这是通过遍历每个下载 url 并使用键作为 url 和值作为延迟填充字典来完成的。当脚本继续从 "fastest" 下载 url 下载时,它失败并返回 nil。
我假设这是因为脚本在继续,而完成处理程序仍然是 运行,字典中还没有任何内容,但我该如何解决这个问题?
基于@vadian 在
的回答
...
let group = DispatchGroup()
var share_response = [String: Double]()
var package_sources: NSArray! = ["https://www.jss1.com/Share", "https://www.jss2.com/Share", "https://www.jss3.com/Share"]
let package_names: String = ["Dummy1.pkg", "Dummy2.pkg", "Dummy3.pkg"]
// Loop through the package sources and find the one with
// the lowest latency.
for share_url in package_sources {
group.enter()
getPKG(pkgName: "Dummy.pkg", dpUrl: share_url, completion: {
group.leave()
dlObject in
if dlObject.latency != nil {
share_response[share_url] = dlObject.latency
} else {
debugPrint("nothing yet")
}
return dlObject
})
}
group.notify(queue: DispatchQueue.main) {
let final_download_url = share_response.min { a, b in a.value < b.value }
// Here is where it breaks and responds with nil
for package in package_names {
let download_url = URL(string: final_download_url + package)
Download commands here...
}
}
正在尝试从三个 url 之一下载 PKG 文件。该逻辑基本上从每个下载 url 中找到一个下载的延迟,并将最终下载 url 设置为延迟最低的主机。
import Cocoa
import Alamofire
// Create my object via Struct
struct Package {
var latency: Double?
var name: String?
var statuscode: Int?
var download: Bool?
var downloadUrl: String?
}
// Download the package from the provided download url and return the object
func getPKG(pkgName: String, dpUrl: String, completion: @escaping (Package) -> (Package)) {
let url = URL(string: "\(dpUrl)\(pkgName)")
let parameters: Parameters = ["foo":"bar"]
Alamofire.download(url, method: .get, parameters: parameters, encoding: JSONEncoding.default, to: destination)
.downloadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
debugPrint("Download Progress...: \(progress.fractionCompleted)")
}
.validate(statusCode: 200..<399)
.response { response in
debugPrint(response.response!)
debugPrint(response.response!.statusCode)
debugPrint(response.timeline.latency)
let dlObject = Package(latency: response.timeline.latency, name: pkgName, statuscode: response.response?.statusCode, download: true, downloadUrl: dpUrl)
completion(dlObject)
}
}
var share_response = [String: Double]()
var package_sources: NSArray! = ["https://www.jss1.com/Share", "https://www.jss2.com/Share", "https://www.jss3.com/Share"]
let package_names: String = ["Dummy1.pkg", "Dummy2.pkg", "Dummy3.pkg"]
// Loop through the package sources and find the one with
// the lowest latency.
for share_url in package_sources {
getPKG(pkgName: "Dummy.pkg", dpUrl: share_url, completion: {
dlObject in
if dlObject.latency != nil {
share_response[share_url] = dlObject.latency
} else {
debugPrint("nothing yet")
}
return dlObject
})
}
let final_download_url = share_response.min { a, b in a.value < b.value }
// Here is where it breaks and responds with nil
for package in package_names {
let download_url = URL(string: final_download_url + package)
Download commands here...
}
这是通过遍历每个下载 url 并使用键作为 url 和值作为延迟填充字典来完成的。当脚本继续从 "fastest" 下载 url 下载时,它失败并返回 nil。
我假设这是因为脚本在继续,而完成处理程序仍然是 运行,字典中还没有任何内容,但我该如何解决这个问题?
基于@vadian 在
...
let group = DispatchGroup()
var share_response = [String: Double]()
var package_sources: NSArray! = ["https://www.jss1.com/Share", "https://www.jss2.com/Share", "https://www.jss3.com/Share"]
let package_names: String = ["Dummy1.pkg", "Dummy2.pkg", "Dummy3.pkg"]
// Loop through the package sources and find the one with
// the lowest latency.
for share_url in package_sources {
group.enter()
getPKG(pkgName: "Dummy.pkg", dpUrl: share_url, completion: {
group.leave()
dlObject in
if dlObject.latency != nil {
share_response[share_url] = dlObject.latency
} else {
debugPrint("nothing yet")
}
return dlObject
})
}
group.notify(queue: DispatchQueue.main) {
let final_download_url = share_response.min { a, b in a.value < b.value }
// Here is where it breaks and responds with nil
for package in package_names {
let download_url = URL(string: final_download_url + package)
Download commands here...
}
}