swift - 在 Swift 上发出多个网络请求
问题描述
我正在尝试从学校课程目录网站下载数据。我在变量 UrlBook 中有 64 个 Url。我已经成功编写了代码来下载课程集合,并使用完成处理程序方法将它们从单个 url转换为单个主题对象。我真的不知道我应该如何实现从 64 url 收集所有主题并最终将它们变成目录对象(它包含主题对象列表)。
我已经阅读了很多关于异步和同步处理的文章和帖子,这让我很困惑。我非常感谢简单直接的代码来帮助我解决这个问题。感谢你们!
let urlBook = getUrlFromBook()
func fetchClassInfo(url:URL,completion: @escaping ([clase])-> Void){
let task = URLSession.shared.dataTask(with: url){(data, response, error) in
let jsonDecoder = JSONDecoder()
if let data = data,
let collection:[clase] = try? jsonDecoder.decode([clase].self, from: data){
completion(collection)
}else{
print("Either no data was returned, or data was not properly decoded.")
//completion(nil)
}
}
task.resume()
}
fetchClassInfo(url:urlBook.book[0]){(clase) in
let newSubject = makeNewSubject(subjectIndex: 0, collectionOfCourse: clase)
var masterCatalog = catalog(subjectCollection: [])
masterCatalog.addSubject(newSubject: newSubject)
}
解决方案
您基本上可以创建如下所示的逻辑。这个函数接受一个 url 列表并返回一个完整的 Subject 列表。您可以根据需要修改模型等。在这个函数中;DispatchGroup
是在调用之前等待所有请求完成,completion
并且DispatchQueue
在将主题附加到数组时防止“数据竞争”。
func downloadUrls(urls: [URL], completion: @escaping ([Subject]) -> Void) {
var subjectCollection: [Subject] = []
let urlDownloadQueue = DispatchQueue(label: "com.urlDownloader.urlqueue")
let urlDownloadGroup = DispatchGroup()
urls.forEach { (url) in
urlDownloadGroup.enter()
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
guard let data = data,
let subject = try? JSONDecoder().decode(Subject.self, from: data) else {
// handle error
urlDownloadQueue.async {
urlDownloadGroup.leave()
}
return
}
urlDownloadQueue.async {
subjectCollection.append(subject)
urlDownloadGroup.leave()
}
})
}
urlDownloadGroup.notify(queue: DispatchQueue.global()) {
completion(subjectCollection)
}
}
推荐阅读
- reactjs - 如何在 React 中更改 svg 样式图标的颜色?
- postgresql - 如何使用 INSERT 规则返回值创建视图 - 规则定义中没有 INSERT
- angular - ANGULAR 10 Keycloak 被 CORS 策略阻止
- javascript - 使 DIV 占用另一个隐藏的 DIV 的空间
- python - 测试 GPU 是否可用于 tensorflow
- python - 使用 pyinstaller 后 python win32api 失败
- java - 如何将 KeyEvent 发送到 JFrame 组件?
- c# - HtmlAgilityPack 删除节点(头)不起作用
- html - 如何在 React 中渲染由 createElement() 创建的元素?
- fail2ban - 为特定的 url 设置 Fail2ban