Ashwin Sathawane
Ashwin Sathawane

Reputation: 381

Table view lag while displaying images from network

I am creating a small app for displaying images in TableView from Flickr. The app works fine but i am facing a issue while scrolling table view, my tableview lags a lot. I think the issue might be with GCD or Threads, i am new to networking and GCD, this is my code getting images from Flickr API.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let cell = flickrTableView.dequeueReusableCellWithIdentifier("cell") as! FlickerTableCell
  let flickr = flickrArray[indexPath.row]
  dispatch_async(dispatch_get_main_queue(), {
   cell.imageViewFlickr.image = flickr.getFlickrImage()
  })

   cell.labelFlickrTitle.text = flickr.title
   return cell
}

// function to get images from flickr

func getFlickrImage()->UIImage{
   let imageURL = NSURL(string: "https://farm\(farm).staticflickr.com/\(server)/\(photoId)_\(secret)_m.jpg")!
   var flickrImage = UIImage()
   if let imageData = NSData(contentsOfURL: imageURL) {
           flickrImage = UIImage(data: imageData)!

   } else {

       print("Image does not exist at \(imageURL)")
   }
   return flickrImage
}

Upvotes: 0

Views: 76

Answers (1)

Abhijeet Mallick
Abhijeet Mallick

Reputation: 1750

Your method to fetch image from network that is getFlickrImage() is sync method so table cell waits for its response and as the network call is in main thread it freezes or lags the UI. you can wrap your network call in async method and use completion handler to update the UI in main thread such as:

func getFlickrImage(completion:UIImage ->()){
    let imageURL = NSURL(string: "https://farm\(farm).staticflickr.com/\(server)/\(photoId)_\(secret)_m.jpg")!
    var flickrImage = UIImage()

    let download = dispatch_queue_create("download", nil)
    dispatch_async(download) {

        if let imageData = NSData(contentsOfURL: imageURL) {
            dispatch_async(dispatch_get_main_queue(), {
                flickrImage = UIImage(data: imageData)!
                completion(flickrImage)
            })
        } else {

            print("Image does not exist at \(imageURL)")
            completion(flickrImage)
        }
    }

}

Your cellForRowAtIndexPath will be like:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = flickrTableView.dequeueReusableCellWithIdentifier("cell") as! FlickerTableCell
    let flickr = flickrArray[indexPath.row]
    flickr.getFlickrImage { (photo) in
        dispatch_async(dispatch_get_main_queue(), {
            cell.imageViewFlickr.image = photo
        })
    }
    cell.labelFlickrTitle.text = flickr.title
    return cell
}

Upvotes: 1

Related Questions