简体   繁体   中英

Using DispatchGroup with Streaming API?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM