Hamid
Hamid

Reputation: 289

Swift 3 unclear delay in filling up labels in a collection view

I am reading products data from API and print down the ids to make sure data has been fetched successfully. Then, I put products titles into collection view label.

The strange thing here is that the list of ids are printed very fast. Then the app wait for few seconds till the collectionView is populated.

I couldn't understand why the delay is occurring as I have only 10 products, which should not take any time for loading and I already made a loop over them and printed ids successfully in no time!

The following code shows exactly what I have done yet. I hope someone can help me figure out where is the bottle-nick:

import UIKit

class TestViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    @IBOutlet weak var collectionView: UICollectionView!

    var jsonData : [[String: Any]] = [[:]]

    override func viewDidLoad() {
        super.viewDidLoad()

        var request = URLRequest(url: URL(string: shopUrl + "/admin/products.json")!)
        request.httpMethod = "GET"

        URLSession.shared.dataTask(with:request, completionHandler: {(data, response, error) in
            if error != nil {
                print(error)
            } else {
                do {
                    guard let json = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] else { return }

                    guard let root = json?["products"] as? [[String: Any]] else { return }
                    self.jsonData = root
                    self.collectionView.reloadData()

                    print("This will be printed very fast!")

                    for product in root {
                        guard let id = product["id"] as? Int else { return }
                        print(id)
                    }
                }
            }
        }).resume()

    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let data = self.jsonData[indexPath.row]

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TestCollectionViewCell", for: indexPath) as!     TestCollectionViewCell

        if let title = data["title"] as? String {
            cell.titleLabel.text = title
        }

        return cell
    }
}

Upvotes: 0

Views: 634

Answers (1)

Tj3n
Tj3n

Reputation: 9923

Try call your reloadData in main thread:

DispatchQueue.main.async {
   self.collectionView.reloadData()
}

The problem is that URLSession callback handler is still in background thread so it wont update your UI fast, so you have to switch back to main thread before update any UI after call network request with URLSession

Upvotes: 2

Related Questions