Mike
Mike

Reputation: 837

How should I use DispatchGroup for two url requests?

I am using DispatchGroup for two url requests but didn't get any data. I tried each method separately without DispatchGroup, it works fine. So the problem is that I didn't use DispatchGroup correctly. Please help.

    let buildingManager =  BuildingManager()
    let anaManager = AnalyticsManager()
    let group = DispatchGroup()
    let queue = DispatchQueue.global(qos: .background)

    queue.async(group: group) {
        buildingManager.getBuildingInfos(completion: { [weak self] (buildings, success) in
            guard let self = self else {return}

            if success {
                self.buildings = buildings
                print("success")
            } else {
                print("No building infos")
            }
        })
    }

    queue.async(group: group) {
        anaManager.getAnaData(completion: {[weak self] (anaData, success) in
            guard let self = self else {return}

            if success {
                self.analyticsData = anaData
                print("success")
            } else {
                print("No analytics data")
            }
        })
    }

        group.notify(queue: DispatchQueue.main) { [weak self] in
            self?.dataTableView.reloadData()
        }

Upvotes: 0

Views: 655

Answers (2)

rmaddy
rmaddy

Reputation: 318804

I would refactor just a bit to explicitly enter and leave your group as needed. The use of queue.async(group:) should only be used when the code in the block is not async already.

let buildingManager =  BuildingManager()
let anaManager = AnalyticsManager()
let group = DispatchGroup()
let queue = DispatchQueue.global(qos: .background)

queue.async {
    group.enter()
    buildingManager.getBuildingInfos(completion: { [weak self] (buildings, success) in
        defer { group.leave() }

        guard let self = self else {return}

        if success {
            self.buildings = buildings
            print("success")
        } else {
            print("No building infos")
        }
    })

    group.enter()
    anaManager.getAnaData(completion: {[weak self] (anaData, success) in
        defer { group.leave() }

        guard let self = self else {return}

        if success {
            self.analyticsData = anaData
            print("success")
        } else {
            print("No analytics data")
        }
    })

    group.notify(queue: DispatchQueue.main) { [weak self] in
        self?.dataTableView.reloadData()
    }
}

Upvotes: 1

Augusto
Augusto

Reputation: 4243

In the past, I had same problem that you, and I learned a bit more of parallel process in Swift. I can be wrong, but in your place I would use the OperationQueue. You can try do this:

let queue = OperationQueue()

queue.addOperation {
 buildingManager.getBuildingInfos(completion: { [weak self] (buildings, success) in
            guard let self = self else {return}

            if success {
                self.buildings = buildings
                print("success")
            } else {
                print("No building infos")
            }  

            DispatchQueue.main.async {
                self?.dataTableView.reloadData()
            }
        })
}

queue.addOperation {
 anaManager.getAnaData(completion: {[weak self] (anaData, success) in
            guard let self = self else {return}

            if success {
                self.analyticsData = anaData
                print("success")
            } else {
                print("No analytics data")
            }

                DispatchQueue.main.async {
                    self?.dataTableView.reloadData()
                }
        })
}
  • This is more a opinion than answer.

Ref.: https://www.raywenderlich.com/5293-operation-and-operationqueue-tutorial-in-swift

Upvotes: 0

Related Questions