迭代APi结果的最佳方式是什么,并知道何时完成?
问题描述:
我从FatSecret API获取数据。简而言之,我有几个食物ID需要从中获取数据,迭代它们以将卡路里加在一起。每个人都必须是一个单独的电话。由于这些不会在主线程中运行,因此确定它们何时完成的最佳方法是什么?目前,我使用每次调用完成时迭代一次的变量来追踪它,但我觉得可能有更好的方法。迭代APi结果的最佳方式是什么,并知道何时完成?
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
。当您的所有请求都完成时,它会触发一个异步回调模块。
DispatchGroup:
DispatchGroup允许工作的总同步。您可以使用 来提交多个不同的工作项目,并跟踪它们何时全部完成,即使它们可能运行在不同的队列中。当所有 指定任务完成时,如果无法取得进展,则此行为可能会有所帮助。
在你的代码,这将是这样的:
// ...
// 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 :)
})
}
这正是我一直在寻找。谢谢! – user1328035
不客气!祝你的项目好运:) – Alex