如何在同一函数中为 2 个 Alamofire 请求只有 1 个完成处理程序
Posted
技术标签:
【中文标题】如何在同一函数中为 2 个 Alamofire 请求只有 1 个完成处理程序【英文标题】:How to have only 1 completion handler for 2 Alamofire request in the same function 【发布时间】:2017-12-23 04:42:03 【问题描述】:我有一个函数,里面有 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()
【问题讨论】:
【参考方案1】:更好的解决方案
使用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() 的闭包。
【讨论】:
@kevinvu 乐于助人:)【参考方案2】:如下所示更新您的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 上检查此代码,所以如果您对此代码有任何问题,请告诉我。
【讨论】:
有效!我只需要将 self 放在第二个请求调用中以供参考。非常感谢!以上是关于如何在同一函数中为 2 个 Alamofire 请求只有 1 个完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章