title: UICollectionView displays wrong images in cells
body: <p>I am building a UITableView that is going to have cells with different layouts in them. The cell I am having issues with has a UICollectionView embedded in it that is generated from an API. </p>
  
  <p>The category name and id populate in the cell correctly, but the images in the UICollectionView do not. The images load, but they are not the right ones for that category. <a href="https://i.stack.imgur.com/rgegI.png" rel="noreferrer">Screen capture of how the collection is loading currently</a></p>
  
  <p>Some of the things I've tried:</p>
  
  <ul>
  <li><p>Hard-coding the ids for each one of the categories instead of dynamically generating them. When I do this, the correct images load (sometimes but not always) ... and if they do load correctly, when I scroll the images change to wrong ones</p></li>
  <li><p>The prepareForReuse() function ... I'm not exactly sure where I would put it and what I would reset in it (I have code I believe already kind of nils the image out [code included below])</p></li>
  </ul>
  
  <p>I have spent a few hours trying to figure this out, but I am stuck ... any suggestions would be appreciated.</p>
  
  <p>My View Controller:</p>
  
  <pre><code>class EcardsViewController: BaseViewController {
  
  @IBOutlet weak var categoryTable: UITableView!
  
  var categories = [CategoryItem]()
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      // Do any additional setup after loading the view.
      self.categoryTable.dataSource! = self
      self.categoryTable.delegate! = self
  
      DispatchQueue.main.async {
          let jsonUrlString = "https://*********/******/category"
          guard let url = URL(string: jsonUrlString) else { return }
  
          URLSession.shared.dataTask(with: url) { (data, response, err) in
              guard let data = data else { return }
  
              if err == nil {
                  do {
                      let decoder = JSONDecoder()
                      let ecardcategory = try decoder.decode(Category.self, from: data)
                      self.categories = ecardcategory.category
                      self.categories.sort(by: {$0.title &lt; $1.title})
                      self.categories = self.categories.filter{$0.isFeatured}
                  } catch let err {
                      print("Err", err)
                  }
  
                  DispatchQueue.main.async {
                      self.categoryTable.reloadData()
                  }
              }
          }.resume()
      }
  }
  
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }
  
  }
  
  extension EcardsViewController: UITableViewDelegate, UITableViewDataSource {
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
          return categories.count
      }
  
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
              let cell = tableView.dequeueReusableCell(withIdentifier: "EcardsCategoriesTableViewCell", for: indexPath) as! EcardsCategoriesTableViewCell
              cell.categoryName.text = ("\(categories[indexPath.row].title)**\(categories[indexPath.row].id)")
              cell.ecardCatId = String(categories[indexPath.row].id)
              return cell
  
      }
  
  }
  </code></pre>
  
  <p>My Table Cell:</p>
  
  <pre><code>class EcardsCategoriesTableViewCell: UITableViewCell {
  
  @IBOutlet weak var categoryName: UILabel!
  @IBOutlet weak var thisEcardCollection: UICollectionView!
  
  
  var ecardCatId = ""
  var theseEcards = [Content]()
  let imageCache = NSCache&lt;NSString,AnyObject&gt;()
  
  override func awakeFromNib() {
      super.awakeFromNib()
  
      // Initialization code
      self.thisEcardCollection.dataSource! = self
      self.thisEcardCollection.delegate! = self
  
      DispatchQueue.main.async {
          let jsonUrlString = "https://**********/*******/content?category=\(self.ecardCatId)"
          guard let url = URL(string: jsonUrlString) else { return }
          URLSession.shared.dataTask(with: url) { (data, response, err) in
              guard let data = data else { return }
  
              if err == nil {
                  do {
                      let decoder = JSONDecoder()
                      let ecards = try decoder.decode(Ecards.self, from: data)
                      self.theseEcards = ecards.content
                      self.theseEcards = self.theseEcards.filter{$0.isActive}
  
                  } catch let err {
                      print("Err", err)
                  }
  
                  DispatchQueue.main.async {
                      self.thisEcardCollection.reloadData()
                  }
              }
          }.resume()
      }
  }
  
  override func setSelected(_ selected: Bool, animated: Bool) {
      super.setSelected(selected, animated: animated)
  
      // Configure the view for the selected state
  
  }
  }
  
  extension EcardsCategoriesTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource {
  
  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int {
      return theseEcards.count &gt; 7 ? 7 : theseEcards.count
  }
  
  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -&gt; UICollectionViewCell {
      let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "EcardCategoriesCollectionViewCell", for: indexPath) as! EcardCategoriesCollectionViewCell
      cell.ecardImage.contentMode = .scaleAspectFill
      let ecardImageLink = theseEcards[indexPath.row].thumbSSL
      cell.ecardImage.downloadedFrom(link: ecardImageLink)
      return cell
  }
  
  }
  </code></pre>
  
  <p>Collection View Cell:</p>
  
  <pre><code>class EcardCategoriesCollectionViewCell: UICollectionViewCell {
      @IBOutlet weak var ecardImage: UIImageView!
  }
  </code></pre>
  
  <p>Extension to "download" image:</p>
  
  <pre><code>extension UIImageView {
  
  func downloadedFromReset(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit, thisurl: String) {
      contentMode = mode
      self.image = nil
      // check cache
      if let cachedImage = ImageCache.shared.image(forKey: thisurl) {
          self.image = cachedImage
          return
      }
  
      URLSession.shared.dataTask(with: url) { data, response, error in
          guard
              let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
              let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
              let data = data, error == nil,
              let image = UIImage(data: data)
              else { return }
          ImageCache.shared.save(image: image, forKey: thisurl)
          DispatchQueue.main.async() {
              self.image = image
          }
          }.resume()
  }
  func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
      guard let url = URL(string: link) else { return }
      downloadedFromReset(url: url, contentMode: mode, thisurl: link)
  }
  }
  </code></pre>