0

I am new to iOS programming and I have a conceptual and a functional question. I tried looking at SO threads but did not get an exact question matching my situation.

I am building a simple screen where I display a list of user names along with their avatars - something like your typical Contacts screen.

I am using a UITableview for this purpose. I first make a HTTP GET call to retrieve the list of users which returns a JSON with their names and the url to download their image. I then will store this info into Core Data and cache the images as well.

I am struggling with the part where I download the images and set it into the UIImageView.image.

  1. Conceptually, which method should I use to get the names and the image urls - viewDidLoad or viewWillAppear? It seems to me that I should use viewWillAppear as in subsequent calls, I will be getting the list from Core Data and there is no network activity?
  2. tableView:cellForRowAtIndexPath is the function that I use to get the image corresponding to each row. Is this correct?

Any help or pointing towards a duplicate question will help much! Thanks!

srinij
  • 471
  • 6
  • 10

2 Answers2

0
  1. Get the names and urls in viewDidLoad.
  2. Make a custom UITableViewCell that takes a url for it's image. In didSet (for the url property), download the image and set the image for the UIImageView:

    class CustomTableViewCell: UITableViewCell
        var url: URL? = nil {
            didSet {
                //download and set image.
                //example code can be found at the link below
            }
        }
    }
    

    Download image from url

Community
  • 1
  • 1
Jake
  • 13,097
  • 9
  • 44
  • 73
0

You can download all images Async process from below code...

Swift 3

private let downloadQueue = DispatchQueue(label: "me.readytoImage.downloadQueue", attributes: [])

class MainViewController: UIViewController {

fileprivate var photos = [URL]()
fileprivate var cache = NSCache<AnyObject, AnyObject>()

// MARK: - Image Downloading block
    fileprivate func downloadPhoto(_ url: URL, completion: @escaping (_ url: URL, _ image: UIImage) -> Void) {
        downloadQueue.async(execute: { () -> Void in
            if let data = try? Data(contentsOf: url) {
                if let image = UIImage(data: data) {
                    DispatchQueue.main.async(execute: { () -> Void in
                        self.cache.setObject(image, forKey: url as AnyObject)
                        completion(url, image)
                    })
                }
            }
        })
    }

Call Block

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! PhotoCell
        let url = photos[indexPath.item]
        //check cache images
        let image = cache.object(forKey: url as AnyObject) as? UIImage

        cell.imageView.backgroundColor = UIColor(white: 0.95, alpha: 1)
        cell.imageView.image = image
        //Downloading images
        if image == nil {
            downloadPhoto(url, completion: { (url, image) -> Void in
                let indexPath_ = collectionView.indexPath(for: cell)
                if indexPath == indexPath_ {
                    cell.imageView.image = image
                }
            })
        }
        return cell
    }

otherwise you can also user Kingfisher SDK for download your images in Swift 3.

let url = json["image"] as? String
cell.imageProfile.kf.setImage(with: URL(string: url!))
Anand Nimje
  • 6,163
  • 4
  • 24
  • 43
  • Thanks! This worked really well. Started using Kingfisher which I did not know about! Was using Picasso in Android and was looking for its iOS version and realised they do not have one. – srinij Feb 03 '17 at 03:56