Tung Vu Duc
Tung Vu Duc

Reputation: 1662

Break for loop from completion handler

I have 4 type of category: ["PR", "Pickup", "Recommend", "New"]

For each type I need to call to server to fetch articles. The problem is that I want to stop fetching if I had enough 20 articles. I don't want to handle every single callback. Is there a better way?

I'm using DispatchGroup but it doesn't work as expected. Here is my code:

let types: [FeedTimeline] = [.special, .pr, .pickup, .lastPost]
for type in types {
    dispatchGroup.enter()
    self.getArticles(of: type, page: currentPage) { [unowned self] (articles) in
        self.articles.append(contentsOf: articles ?? [])
        self.dispatchGroup.leave()
    }
    dispatchGroup.notify(queue: .main) {
        if self.articles.count >= 20 {
            self.currentSubType = type
            //I want to stop request here 
        }
        self.tableView.reloadData()
    }
}

Upvotes: 0

Views: 190

Answers (1)

PGDev
PGDev

Reputation: 24341

Instead of checking the articles count in dispatchGroup's notify closure, you need to do it before calling getArticles(of:page:handler:) method, i.e.

    types.forEach { (type) in
        if self.articles.count < 20 {
            dispatchGroup.enter()
            self.getArticles(of: type, page: currentPage) {[unowned self] (articles) in
                self.articles.append(contentsOf: articles ?? [])
                dispatchGroup.leave()
            }
        }
    }

Next the dispatchGroup's notify closure goes like,

dispatchGroup.notify(queue: .main) {
    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
}

Upvotes: 1

Related Questions