我有一个带有2个Alamofire请求的函数,里面有一个完成处理程序。我想要从服务器下载完两个请求后重新加载我的collectionView。我在函数中有一个完成处理程序,但它被调用两次导致我的collectionView重新加载两次,我只想重新加载一次。有没有办法可以这样做?非常感谢你!
func getFeedVideos(completion: @escaping (_ completedDownloadVideo: Bool) -> ()){
Alamofire.request(youTubeUrl, method: .get, parameters: ["part":"snippet","maxResults": "20","nextPageToken" : "pageToken", "playlistId": playListId, "key": googleAPIKey], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
guard let data = response.data else {return}
do {
let json = try JSONDecoder().decode(serverData.self, from: data)
self.dataFromAPI = json.items
completion(true)
} catch let jsonErr{
print(jsonErr)
}
}
Alamofire.request(youTubeChannelUrl, method: .get, parameters: ["part":"snippet", "key": googleAPIKey, "id": youTubeChannelId], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
guard let data = response.data else {return}
do {
let json = try JSONDecoder().decode(channelInfo.self, from: data)
self.channelData = json.items
completion(true)
} catch let jsonErr{
print(jsonErr)
}
}
}
以下是我在ViewDidLoad中调用函数的方法
override func viewDidLoad() {
super.viewDidLoad()
getFeedVideos { (complete) in
if complete{
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
}
}
}
答案 0 :(得分:2)
更好的解决方案
使用DispatchGroup
以下是示例
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
Alamofire.request(youTubeUrl, method: .get, parameters: ["part":"snippet","maxResults": "20","nextPageToken" : "pageToken", "playlistId": playListId, "key": googleAPIKey], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
guard let data = response.data else {return}
do {
let json = try JSONDecoder().decode(serverData.self, from: data)
self.dataFromAPI = json.items
completion(true)
} catch let jsonErr{
print(jsonErr)
}
dispatchGroup.leave()
}
dispatchGroup.enter()
Alamofire.request(youTubeChannelUrl, method: .get, parameters: ["part":"snippet", "key": googleAPIKey, "id": youTubeChannelId], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
guard let data = response.data else {return}
do {
let json = try JSONDecoder().decode(channelInfo.self, from: data)
self.channelData = json.items
completion(true)
} catch let jsonErr{
print(jsonErr)
}
dispatchGroup.leave()
}
这是魔术线
dispatchGroup.notify(queue: .main) {
print("Both functions complete ")
}
每次调用enter()之后必须调用leave(),之后该组将调用提供给notify()的闭包。
答案 1 :(得分:1)
更新您的getFeedVideos
方法,如下所示:
func getFeedVideos(completion: @escaping (_ completedDownloadVideo: Bool) -> ()){
Alamofire.request(youTubeUrl, method: .get, parameters: ["part":"snippet","maxResults": "20","nextPageToken" : "pageToken", "playlistId": playListId, "key": googleAPIKey], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
guard let data = response.data else {return}
do {
let json = try JSONDecoder().decode(serverData.self, from: data)
self.dataFromAPI = json.items
Alamofire.request(youTubeChannelUrl, method: .get, parameters: ["part":"snippet", "key": googleAPIKey, "id": youTubeChannelId], encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
guard let data = response.data else {return}
do {
let json = try JSONDecoder().decode(channelInfo.self, from: data)
self.channelData = json.items
completion(true)
} catch let jsonErr{
print(jsonErr)
}
}
} catch let jsonErr{
print(jsonErr)
}
}
}
正如我在您的代码中看到的那样,您在两个API调用中都在调用completion(true)
这就是为什么多次重新加载。在我的代码中,我已将您的第一个API调用中的completion(true)
替换为另一个API调用,因此一旦您的两个API调用完成,您的completion(true)
将会调用。
希望这会有所帮助。
注意:强>
没有在Xcode上检查此代码,请告诉我您是否对此代码有任何疑问。