我正在从 FatSecret API 获取数据。简而言之,我有几个食物 ID 需要从中获取数据,对它们进行迭代以将卡路里加在一起。每个都必须是一个单独的调用。由于这些不在主线程上运行,确定它们何时全部完成的最佳方法是什么?目前,我使用一个变量来跟踪它,每次调用完成时该变量都会迭代一个,但我觉得可能有更好的方法。
for thisFoodId in foodIds {
let endpointURL = <URL WITH FOODID>
guard let url = URL(string: endpointURL) else {
return
}
let urlRequest = URLRequest(url: url)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: urlRequest, completionHandler: {
(data, response, error) in
guard error == nil else {
return
}
guard let responseData = data else {
return
}
do {
guard let thisData = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject] else {
return
}
let calories = thisData["calories"]
self.totalCalories += calories
tracker += 1
if tracker == foodIds.count {
// RUN COMPLETION CODE
}
}
}
最佳答案
您可以使用 DispatchGroups
。当您的所有请求完成时,它将触发一个异步回调 block 。
调度组:
DispatchGroup allows for aggregate synchronization of work. You can use them to submit multiple different work items and track when they all complete, even though they might run on different queues. This behavior can be helpful when progress can’t be made until all of the specified tasks are complete.
在你的代码中,它会像这样:
// ...
// Create the DispatchGroup:
let dispatchGroup = DispatchGroup()
for thisFoodId in foodIds {
// Enter the DispatchGroup:
dispatchGroup.enter()
// ...
let task = session.dataTask(with: urlRequest, completionHandler: {
(data, response, error) in
// ...
do {
// ...
if tracker == foodIds.count {
// Leave the DispatchGroup
dispatchGroup.leave()
}
}
})
// When all your tasks have completed, notify your DispatchGroup to run your work item:
dispatchGroup.notify(queue: DispatchQueue.main, execute: {
// All your async requests are finished here, do whatever you want :)
})
}
关于swift - 迭代 API 的结果并知道它何时完成的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46414631/