我从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
}
}
}
答案 0 :(得分:4)
您可以使用// ...
// 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 :)
})
}
。当您的所有请求都完成后,它将触发异步回调块。
<强> DispatchGroup:强>
DispatchGroup允许工作的聚合同步。您可以 使用它们提交多个不同的工作项并跟踪它们 一切都完整,即使它们可能在不同的队列上运行。这个 当所有的进展都无法取得进展时,行为可能会有所帮助 指定的任务已完成。
在您的代码中,它会这样:
https://monitoring.us-west-1.amazonaws.com/doc/2010-08-01/?Action=PutMetricData