TonyGW TonyGW - 2 months ago 14
Swift Question

Swift 2: UICollectionView - is it possible to return cell asynchronously?

I have a

UICollectionView
in a UIView container, and I use it for displaying images (as an array of
PFFile
) attached to a
PFObject
stored in Parse. I know I could fetch the the PFFile/image synchronously in my current implementation (see below working code for synchronous loading), but I would really like to make this an asynchronous process.

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("attachedImageCell", forIndexPath: indexPath) as! AttachedImageCollectionViewCell

if let uploadImageFile = attachedImageFiles[indexPath.row] as? PFFile {



do {
var imageData: NSData
try imageData = uploadImageFile.getData()
cell.imageView.image = UIImage(data: imageData)
} catch let err as NSError {
print("error getting image file data: \(err)")
}

/*
//asynchronously getting image data - don't know how to return cell here
uploadImageFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
if error != nil {
//TODO: show error in download
}
if imageData != nil {
cell.imageView.image = UIImage(data: imageData!)
}
})
*/
}

return cell
}


One way I have been contemplating is to have the
AttachedImageCollectionViewCell
object observe its
UIImageView
, once a UIImage file (a pointer) is assigned to it, it will go fetching the the
PFFile
from Parse and parse it to
NSData
, which is used for the UIImage.

As I am still on the learning curve of mastering Swift, I am not sure how feasible this approach might be. So I am all ears for any ideas here, thanks!

Answer

So in your code where you create the cell, you ensure, you set the image to cell asynchronously using the library-

https://github.com/natelyman/SwiftImageLoader/blob/master/ImageLoader.swift

//Create cell in usual way
//Code here to create the cell 

//Load the image needed by the cell asynchronously
ImageLoader.sharedLoader.imageForUrl(urlString, completionHandler:{(image: UIImage?, url: String) in
    cell.image = image
}) 

HTH