Storing images on Parse is easy, we just need to create a class that contains a File column for storing the image file. With ParseUI, it’s also very easy to show these images in the app using a PFImageView. All we need is to set the file property on the image view and call loadInBackground. If you need to learn more about how to handle images with Parse, here’s a great tutorial.

But what about storing and displaying GIF images? You can store the GIF images in the File column on parse, but unfortunately, displaying them on the app is not as straightforward as using a PFImageView. Let’s see how we can display the GIF images from Parse in an iOS app using FLAnimatedImage.

Start by adding the following to your Podfile

pod 'FLAnimatedImage', '~> 1.0'

We will now use an FLAnimatedImageView instead of the PFImageView. This means that we need to manually handle all the fancy file downloading stuff now. Don’t worry, Parse still makes it easy to download the data for a PFFile.

[image.imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
  if ([[image.file.name pathExtension] caseInsensitiveCompare:@"gif"] ==  NSOrderedSame) {
    // Set the animated image on FLAnimatedImageView
    animatedImageView.animatedImage = [FLAnimatedImage animatedImageWithGIFData:data]; 
  } else {
    // Use a non animated UIImage
    animatedImageView.image = [UIImage imageWithData:data];
  }
}];

This is all you need to display GIF images in the app. Of course, you will need to handle the error (if there is any). And, if you are using this in a table/collection view, don’t forget that the getDataInBackgroundWithBlock: may take some time and actually be called after the cell is reused for some other object. This was automatically handled for you when you use a PFImageView, but here, you need to make sure you don’t display an incorrect image from a previous cell. Add this simple check in the block to avoid this:

NSString *imageId = self.image.objectId;
[self.image.imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
  if (![imageId isEqualToString:self.image.imageId]) {
    // The image has changed for this cell. Skip...
    return;
  }
  
  if ([[self.image.file.name pathExtension] caseInsensitiveCompare:@"gif"] ==  NSOrderedSame) {
    // Set the animated image on FLAnimatedImageView
    animatedImageView.animatedImage = [FLAnimatedImage animatedImageWithGIFData:data]; 
  } else {
    // Use a non animated UIImage
    animatedImageView.image = [UIImage imageWithData:data];
  }
}];

If you ever need help setting this up or have some questions, don’t hesitate to write to me at diwakar.sapan@gmail.com or leave a comment.