Cloudinary Blog

Cloudinary's iOS SDK makes a Swift move for mobile image management

By
Easy upload and display images in your app with iOS SDK

Embedding and managing images and other media content in a mobile application is always challenging. The processes of downloading a media file from the web, storing it on the device, and then displaying it to the user are surprisingly and often frustratingly complex from a coding perspective. In addition, you probably want to add code that enables reusing images rather than downloading it every time, but you have to be smart about it to avoid clogging the precious storage space on your customer's device. Furthermore, your design probably requires that images be displayed in different sizes and DPRs in different devices, but creating and maintaining multiple versions of every image manually is virtually impossible.

In this article, I’ll demonstrate how you can handle all these tasks with just a few simple lines of code using the new Swift-based Cloudinary iOS SDK.

Tell me more

Cloudinary provides a cloud-based service to handle upload, storage, manipulation, and administration of images and other media content. The simple interface, combined with an extensive set of features, is particularly useful to mobile developers: it alleviates the burden of resource management, letting developers focus on their core application's features.

The latest version of the Cloudinary iOS SDK has been completely re-written in Swift and was developed with the following goals:

  • Adopt Swift’s design paradigms
  • Support both Swift 2.3 and Swift 3.0
  • Support developers still using Objective-C
  • Maintain a familiar API to ease the migration from the previous version of the Cloudinary iOS SDK

Getting started

First, make sure you have a Cloudinary account. If you don't have one yet, you can register for a free account.

After you have an account, get the Cloudinary iOS SDK code either using Cocoapods or directly from the github repository.

  • Install from Cocoapods Add a dependency on Cloudinary in your Podfile:

    Copy to clipboard
      target 'MyApp' do
      pod 'Cloudinary', '~> 2.0'
      end

    Then, run the command:

    Copy to clipboard
      $ pod install
  • Sources from github Grab the code from https://github.com/cloudinary/cloudinary_ios.
    See the SDK readme for detailed instructions.

After installing, follow the Configuration instructions in the SDK readme to set up your environment to work with Cloudinary.

Here’s a quick sample of configuring and initiating the Cloudinary SDK. All following code samples will assume this configuration is in place.

Copy to clipboard
import Cloudinary

let config = CLDConfiguration(cloudName="demo")!
let cloudinary = CLDCloudinary(configuration: config)

Image and video manipulations

One of those big challenges we mentioned at the beginning of this article is the huge quantity of different screen sizes and resolutions you need to take into account. You can set up your app to display completely different designs depending on the screen real estate available, but if your different designs require displaying images at different sizes and scales, then preparing and maintaining multiple versions of every graphic quickly becomes unmanageable. And if you also need to resize user-generated content on-the-fly depending on display size, then you absolutely must have an automated solution.

Luckily, it's easy to make these adjustments on-the-fly using Cloudinary transformations with the iOS SDK.

Cloudinary transformations enable you to crop, scale, rotate, add shadows, outlines, backgrounds, and select from a huge set of artistic filters and special effects, simply by setting method values.

And of-course in addition to using these transformations to make your own app design responsive, you can also pass on all of these manipulation capabilities to your users as photo editing features in your app.

As a (major) added bonus, Cloudinary performs a number of automatic optimizations whenever it generates a transformed image. And beyond these, you can also take advantage of special optimization transformations like auto-quality and auto-format to ensure that every image you deliver uses minimum bandwidth while delivering the needed visual quality. For more details, see Image Optimization.

There is also a nice set of video-specific transcoding and transformation options available, including HTTP Live Streaming (HLS) output. The HLS transcoding feature enables you to automatically generate multiple representations at the quality and sizes you need in order to deliver video in the required HLS adaptive bitrate streaming format.
Note: If your iOS app delivers video over cellular networks, and the video exceeds either 10 minutes overall or more than 5 MB of data in a five-minute period, you are required to deliver it using HTTP Live Streaming.

Specifying a transformation and generating a resource URL

Transformations are represented with the CLDTransformation class. Here are a couple of examples. The first scales an image to a width of 500px. The second applies a sepia effect and rounds the corners of an image to a circle or ellipse.

Copy to clipboard
let transformation = CLDTransformation().setWidth(500).setCrop(.scale)
Copy to clipboard
let transformation2 = CLDTransformation().setEffect(.sepia).setRadius("max")

To generate the URL for an image or video asset:

Copy to clipboard
let url = cloudinary.createUrl()
Copy to clipboard
let imageUrl = url.generate("sample")
// https://res.cloudinary.com/demo/sample.jpg

To generate a URL with the transformation we created above:

Copy to clipboard
let imageUrl = url.setTransformation(transformation2).generate("sample")
// https://res.cloudinary.com/demo/e_sepia,r_max/sample.jpg

The entire process can also be combined in a one liner:

Copy to clipboard
let imageUrl = cloudinary.createUrl().setTransformation(CLDTransformation().setEffect(.sepia).setRadius("max")).generate("sample")
// https://res.cloudinary.com/demo/e_sepia,r_max/sample.jpg

For example:

Original Original sepia effect and rounded sepia effect and rounded

Make sure to check out the full list of available image and video transformations!

Delivering media using UI extensions

So now you know how to generate cool looking, optimized images from Cloudinary, but you still need to display them to the user.

The Cloudinary SDK provides extensions to iOS UI elements, which make the presentation of an image easy. These extensions provide a single API that automatically fetches and downloads an image in the background, and sets it to be displayed in the UI.

Extensions are available for:

  • UIView
  • UIImageView
  • UIButton

In the following example, an image that was uploaded with the public id: public_id and a predefined transformation stored in transformation is assigned to the UIImageView variable named photoImageView.

Copy to clipboard
// given a UIImageView named “photoImageView”
photoImageView.cldSetImage(publicId: publicId, cloudinary: cld, transformation: transformation)

For a complete code example, visit our sample application.

Downloading resources

As we explained above, the Cloudinary SDK automatically fetches and downloads your media resources for you as part of the delivery process, but if you just want to download without displaying, or you want to download separately for any other reason, here are the basics of what normally happens behind the scenes:

First, create a downloader instance:

Copy to clipboard
let downloader = cloudinary.createDownloader()

Then fetch an image or video. Below, we use the image URL (imageURL) we created earlier.

To avoid blocking the application during the download, network access is performed asynchronously in a separate thread. Thus you must provide a callback closure to handle the results of the action.

Copy to clipboard
downloader.fetchImage(imageUrl!) { (image, error) in
 // image is an instance UIImage
 // error is an instance of NSError
}

Notice the callback structure: the last parameter is a closure that receives the downloaded image or an error object. In Swift ,this pattern is called a trailing closure. Swift provides syntactic sugar for trailing closures by allowing the parameter to be provided outside the parameter parentheses. Sweet!

Uploading images from your app

Your users want to show the world their latest meal? With the Cloudinary SDK, uploading is a breeze!

The SDK enables you to upload an image from several sources:

In addition to specifying the media file in your upload call, you also need to provide an unsigned upload preset. An unsigned upload preset is a Cloudinary feature that allows your users to upload directly to your Cloudinary account without having to sign the request. This feature is popular among mobile app developers as it provides close control over the uploaded material without requiring the storage of sensitive credentials on the mobile application.

Unsigned upload presets inherently have some protective limitations. For example, users can't overwrite existing images in your account. You can also set additional limitations when you define your upload preset, such as limiting the file size or type of files they can upload. You create and configure the unsigned upload preset in the Cloudinary console.

After you create the upload preset, you specify it in your upload code as follows:

Copy to clipboard
let uploader = cloudinary.createUploader()
uploader.upload(data: imageData, uploadPreset: "presetname") { result, error in
           // do something
       }

The above shows the most basic upload example, but there are also a large number of optional upload parameters you can set in the upload call.

The result of the upload API call is a CLDUploadResult object that provides information about the uploaded image, as well as the public ID of the image and its URL.

Caching

Cloudinary's iOS implementation also puts emphasis on avoiding redundant downloads through caching.

The first time the fetchImage() method is called for a particular resource, Cloudinary stores it in the device cache. Each subsequent time that the fetchImage() method is called, it first tries to find the image in the local cache, and retrieves it from the cache if it was found. If it was not found in the cache, the image is downloaded from Cloudinary, stored in the cache and then returned to the caller. The device cache used for this purpose has a predefined maximum memory and disk space, that is cleaned out in FIFO order to make room for the latest images.

A swift summary

The Cloudinary iOS SDK was developed with a focus on the challenges that iOS developers face, especially uploading and downloading, and device sizing issues. Manipulation features enable you to easily deliver images in different sizes for different devices on-the-fly as well as treating you to a great toolbox of photo manipulation features that you can apply to your images and/or pass on to your users. HLS transcoding enables you to deliver video at the quality and size that best fits each user's device and network connection, and to answer iOS requirements. Optimization and caching features help you to preserve precious bytes and make the most of the available bandwidth with every delivered resource.

And all of this in a nice and neat Swift package that integrates seamlessly with your own Swift or Objective-C code.

Ready to swoop right in? If you don't have a Cloudinary account yet, take a minute to sign up for a free one, and spread your wings!

Recent Blog Posts

Generate Waveform Images from Audio with Cloudinary

This is a reposting of an article written by David Walsh. Check out his blog HERE!
I've been working a lot with visualizations lately, which is a far cry from your normal webpage element interaction coding; you need advanced geometry knowledge, render and performance knowledge, and much more. It's been a great learning experience but it can be challenging and isn't always an interest of all web developers. That's why we use apps and services specializing in complex tasks like Cloudinary: we need it done quickly and by a tool written by an expert.

Read more
Make All Images on Your Website Responsive in 3 Easy Steps

Images are crucial to website performance, but most still don't implement responsive images. It’s not just about fitting an image on the screen, but also making the the image size relatively rational to the device. The srcset and sizes options, which are your best hit are hard to implement. Cloudinary provides an easier way, which we will discuss in this article.

Read more

The Future of Audio and Video on the Web

By Prosper Otemuyiwa
The Future of Audio and Video on the Web

Web sites and platforms are becoming increasingly media-rich. Today, approximately 62 percent of internet traffic is made up of images, with audio and video constituting a growing percentage of the bytes.

Read more

Embed Images in Email Campaigns at Scale

By Sourav Kundu
Embed Images in Email Campaigns at Scale

tl;dr

Cloudinary is a powerful image hosting solution for email marketing campaigns of any size. With features such as advanced image optimization and on-the-fly image transformation, backed by a global CDN, Cloudinary provides the base for a seamless user experience in your email campaigns leading to increased conversion and performance.

Read more
Build the Back-End For Your Own Instagram-style App with Cloudinary

Github Repo

Managing media files (processing, storage and manipulation) is one of the biggest challenges we encounter as practical developers. These challenges include:

A great service called Cloudinary can help us overcome many of these challenges. Together with Cloudinary, let's work on solutions to these challenges and hopefully have a simpler mental model towards media management.

Read more

Build A Miniflix in 10 Minutes

By Prosper Otemuyiwa
Build A Miniflix in 10 Minutes

Developers are constantly faced with challenges of building complex products every single day. And there are constraints on the time needed to build out the features of these products.

Engineering and Product managers want to beat deadlines for projects daily. CEOs want to roll out new products as fast as possible. Entrepreneurs need their MVPs like yesterday. With this in mind, what should developers do?

Read more