swiftconcurrencydispatchgroup

group.notify never called in dispatchGroup


I have group and queue

let group = DispatchGroup()
let queue = DispatchQueue(label: "downloadImages", attributes: .concurrent)

In my function i send 3 requests

func getImages() {
        networkService.getImages(find: film.originalTitle) { [weak self] result in
            guard let self = self else { return }
            self.queue.async(group: self.group) {
                switch result {
                case let .success(posters):
                    guard let unwrappedPostersResult = posters?.results else { return }
                    self.posters?.append(contentsOf: unwrappedPostersResult)
                case let .failure(error):
                    self.view?.failure(error: error)
                }
            }
        }

        networkService.getImages(find: film.originalLanguage) { [weak self] result in
            guard let self = self else { return }
            self.queue.async(group: self.group) {
                switch result {
                case let .success(posters):
                    guard let unwrappedPostersResult = posters?.results else { return }
                    self.posters?.append(contentsOf: unwrappedPostersResult)
                case let .failure(error):
                    self.view?.failure(error: error)
                }
            }
        }

        networkService.getImages(find: "movies") { [weak self] result in
            guard let self = self else { return }
            self.queue.async(group: self.group) {
                switch result {
                case let .success(posters):
                    guard let unwrappedPostersResult = posters?.results else { return }
                    self.posters?.append(contentsOf: unwrappedPostersResult)
                case let .failure(error):
                    self.view?.failure(error: error)
                }
            }
        }

They worked fine but when i add DispatchGroup group.notify() never called

   group.notify(queue: .main) { [weak self] in
            guard let self = self else { return }
            self.view?.success()
        }

How to call group.notify() after completing requests?


Solution

  • When you create DispatchGroup() you need to add group.enter() and group.leave() for all network service.

    let group = DispatchGroup()
    let queue = DispatchQueue(label: "downloadImages", attributes: .concurrent)
    // Enter group
    group.enter() 
    networkService.getImages(find: film.originalTitle) { [weak self] result in
                guard let self = self else { return }
                self.queue.async(group: self.group) {
                    switch result {
                    case let .success(posters):
                        guard let unwrappedPostersResult = posters?.results else { return }
                        self.posters?.append(contentsOf: unwrappedPostersResult)
                      // leave group
                        group.leave()
                    case let .failure(error):
                        self.view?.failure(error: error)
                       // leave group
                       group.leave()
                    }
                }
            }