senty senty - 6 months ago 22
Swift Question

Assigning UIImage to Collection View Cell

I have a CollectionView inside TableViewController. The collection view cells are there for displaying photos of users. However, what I am fetching from database is the url path.

I am also planning to manipulate more on the images data, thus I chose to store them in an array

(but I am not sure if I should use as array of NSURL)..

(I am also using Firebase as backend which lively listens for the changes, that's why I setup the
check part)

class TableViewController: UITableViewController, UICollectionViewDataSource {

@IBOutlet weak var collectionView: UICollectionView!

var profileImages = [NSURL]()

// Database Checks Hits into `retrievePhotos()`

func retrieveUserPhotos(user: AnyObject) {
if let profilePicLink = user["firstImage"]! {
let firstImagePath = profilePicLink as! String

if let fileUrl = NSURL(string: firstImagePath) {
let isIndexValid = profileImages.indices.contains(0)

if (!isIndexValid) {
} else {
profileImages[0] = fileUrl

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1

Until now everyhing works nice. I am fetching the image url successfully now.

But at this point, I got confused on assign the image to UIImage in cell. (I tried using it with Heneke as it seemed easier).

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CollectionViewCell

// below returns fatal error `Index out of range`

// Also tried this but it doesn't update the UIImage.
// I guess it's because it's already loaded once without download of the images from the link get completed:
if profileImages.count > 0 {

return cell


What is the proper way of handling fetching images and assigning to collection view cell's UIImage?


Where to call the reloadItemAtIndexPaths depends on how you're solving the async operations now. Your async operation should be called for every image you are downloading, so that you can update the corresponding row whenever the image for that row has been fetched. In the callback or whatever for that operation, you call


myArrayOfIndexPaths would then contain only 1 item, which is the indexPath for the current row. So, you would have an async fetch method which you call with the current indexPath as a parameter. You add this to an empty myArrayOfIndexPaths, and then you call reload.