swift - 迭代 API 的结果并知道它何时完成的最佳方法是什么?

标签 swift

我正在从 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/

相关文章:

unit-testing - 在 Swift 中测试断言

arrays - 如何找到数组类型 NSDecimalNumber 的总和

ios - 如何创建新 View 或现有 View 的副本

swift - 使用任何 RGB 颜色空间时无法获得有效的 CGContext?

swift - Rxswift + Moya + Moya-ObjectMapper fatal error

ios - 将 UIImage 加载到 WebView Swift 4

IOS如何将JSON字符串保存和加载到内存

ios - Swift TableViewController reuseIdentifier 从不工作

ios - 通知中心值第一次、第二次没有更新

ios - 如何在 Swift 中延迟回电