Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I run the code from the completion Handler before initializing a cell?

Below is the code of my ViewController

class NewsViewController: UIViewController {
    
    let networkManager = NetworkManager()
    var newsArray = [NewsModel]()
    var totalResult:Int = 0
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        networkManager.fetchNewsData(forCoutry: "us", category: "business") {  newsDataModel in
            
            self.totalResult = newsDataModel.totalResults
            
            for article in newsDataModel.articles {
                let news = NewsModel(newsTitle: article.title,
                                     urlToNewsWebSite: article.url,
                                     authorWebSiteName: article.source.name,
                                     urlToImage: article.urlToImage ?? "" )
                
                self.newsArray.append(news)
            }
        }

        collectionView.reloadData()
    }
    
}

extension NewsViewController: UICollectionViewDelegate {
    
    
}

extension NewsViewController: UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! NewsCell
        cell.configureCell()
        cell.initData(news: newsArray[indexPath.item])
        collectionView.reloadData()
        return cell
    }
}

I need to request data from the network, and then process them in a loop in the completion Handler, and fill the newsArray = [NewsModel](), and only then initialise the cell

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! NewsCell
cell.configureCell()
cell.initData(news: newsArray[indexPath.item])
collectionView.reloadData()
return cell

But first, the cell is initialised for me, and only then the code from the completion Handler starts working, I figured it out using the breakpoint.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How can I fix this?

>Solution :

You should return the length of the newsArray here:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return newsArray.count
}

This will cause cellForItemAt to not be called if newsArray is empty (such as when it is initially).

Next, you should move the reloadData call to inside the completion handler, so that cellForItemAt is called after newsArray has items.

networkManager.fetchNewsData(forCoutry: "us", category: "business") { [weak self] newsDataModel in
    self?.totalResult = newsDataModel.totalResults
    
    for article in newsDataModel.articles {
        let news = NewsModel(newsTitle: article.title,
                             urlToNewsWebSite: article.url,
                             authorWebSiteName: article.source.name,
                             urlToImage: article.urlToImage ?? "" )
        
        self?.newsArray.append(news)
    }

    // notice this:
    self?.collectionView.reloadData()
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading