/ / Jaki jest najlepszy sposób na powtórzenie wyników z APi i wiedzieć, kiedy to się skończy? - szybki

Jaki jest najlepszy sposób na powtórzenie wyników z APi i wiedzieć, kiedy to się skończy? - szybki

Otrzymuję dane z interfejsu API FatSecret. Krótko mówiąc, mam kilka identyfikatorów żywności, których potrzebuję, aby uzyskać dane z iteracji nad nimi, aby dodać razem kalorie. Każdy musi być osobnym połączeniem. Ponieważ nie działają one w głównym wątku, jaki jest najlepszy sposób określenia, kiedy wszystkie są zakończone? Obecnie śledzę go za pomocą zmiennej, która iteruje o jeden za każdym razem, gdy połączenie jest zakończone, ale wydaje mi się, że może być lepszy sposób.

    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
}
}
}

Odpowiedzi:

2 dla odpowiedzi № 1

Możesz użyć DispatchGroups. Wywołuje asynchroniczny blok wywołania zwrotnego po zakończeniu wszystkich żądań.

DispatchGroup:

DispatchGroup pozwala na agregacjęsynchronizacja pracy. Możesz użyj ich do przesłania wielu różnych elementów pracy i śledzenia, kiedy one wszystko ukończone, nawet jeśli mogą działać w różnych kolejkach. To zachowanie może być pomocne, gdy postęp nie może być dokonany, dopóki wszystkie określone zadania zostały zakończone.

W twoim kodzie:

// ...

// 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 :)

})

}