0

I'm currently using a DispatchGroup to be notified when two API calls have completed, and then combine both responses into 1 object, that I then return in a completion handler.

This works for rest apis, however once I use this with two streaming calls, the app crashes because of the continuous firing / uneven dispatchGroup.leave count.

What is another way I can accomplish my goal, or is there something I can do to continue to use a DispatchGroup? Below is a quick example to showcase what I'm doing.

func fetchPets(completion: @escaping (Result<[Pet], Error>) -> Void) {
    let dispatchGroup = DispatchGroup()
    let dogs: [Dog] = []
    let cats: [Cat] = []

    // Make streaming call 1
    dispatchGroup.enter()
    fetchDogs(completion: () -> Void) {
        // Do something (transform data) and add dogs to array
        dispatchGroup.leave()
    }

    // Make streaming call 2
    dispatchGroup.enter()
    fetchCats(completion: () -> Void) {
        // Do something (transform data) and add cats to array
        dispatchGroup.leave()
    }

    // Combine both responses once both calls complete
    dispatchGroup.notify(queue: .main) {
        // Do something with the stuff
        let pets = Pet(...)
        completion(pets)
    }
}
Priyashree Bhadra
  • 3,182
  • 6
  • 23
VAlexander
  • 86
  • 6

1 Answers1

0

You can manually count if the two of them finished or not

class YourClass {
    
    var totalRequest = -1
    var requestLoaded = -1
    
    
    func fetchPets() {
        fetchDogs()
        fetchCats()
    }
    
    func fetchDogs() {
        totalRequest += 1
        APICall.getDogsData { (response) in
            self.requestLoaded += 1
            // Do something (transform data) and add dogs to array
            self.checkIfAllRequestLoaded()
        }
    }
    
    func fetchCats() {
        totalRequest += 1
        APICall.getCatsData { (response) in
            self.requestLoaded += 1
            // Do something (transform data) and add cats to array
            self.checkIfAllRequestLoaded()
        }
    }
    
    // Combine both responses once both calls complete
    func checkIfAllRequestLoaded() {
        if requestLoaded == totalRequest {
            // Do something with the stuff
        }
    }
    
}
Solayman Rana
  • 283
  • 3
  • 12
  • 1
    Thanks @Solayman Rana, that's definitely true, the issue is that after the first load they each may return changes at different times and not guaranteed to both change, so I still need a way to account for that. I think you've given me an idea though. – VAlexander Jan 04 '22 at 19:11