Swiftpack.co - Package - NachoSoto/AsyncImageView


Build Status Carthage compatible

This is a Swift framework that provides an easy to use UIImageView subclass for effectively loading and rendering images asynchronously, providing caching, and error handling.


To try it out you can run the Example included in this repo. You'll need to provide your own Flickr API key in ImageFetcher.


Let's assume you have a struct with the image you want to render:

struct Image: Hashable {
    let url: URL

To get started, you need to define your own RendererType.

struct ImageViews {
    typealias RendererType = AnyRenderer<Renderer.RenderData, ImageResult, NoError>
    typealias ImageView = AsyncImageView<Renderer.RenderData, Data, RendererType, RendererType>
    static func createView() -> ImageView {
        return ImageView(
            initialFrame: .zero,
            renderer: Renderer.singleton.renderer
    struct Data: ImageViewDataType {
        let image: Image
        init(image: Image) {
            self.image = image
        func renderDataWithSize(_ size: CGSize) -> Renderer.RenderData {
            return RenderData(imageData: image, size: size)
    final class Renderer {
        let renderer: RendererType
        static let singleton: Renderer = {
            return Renderer()
        init() {
            self.renderer = AnyRenderer(
                    // AsyncImageView ensures that errors are handled explicitly.
                    // See "fallbacks" below for an alternative to this.
                    .logAndIgnoreErrors  { print("Error downloading image: \($0)") }
        // RemoteRenderDataType allows defining a type that represents an image on the Internet.
        public struct RenderData: RemoteRenderDataType {
            public let image: Image
            public let size: CGSize
            public var imageURL: URL {
                return self.image.url

Now, create an instance of ImageView inside your view:

let view = ImageViews.createView()

You can assign values of your Image type to it. This will asynchronously use the renderer to fetch the image and process it as needed.

view.data = Image(url: yourUrl)


RendererTypes are easily composable. Convenience methods are provided for discoverability:


Memory cache

This provides an easy way to cache processed or downloaded images in memory:


Disk cache

First you need to conform your RenderDataType to DataFileType:

public struct RenderData: RenderDataType, DataFileType {
    public let image: Image
    public let size: CGSize
    public var uniqueFilename: String {
        return (self.image.url as NSURL)
            .addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!

Then add the layer of caching to the renderer:


CacheRenderer provides a high level of customization to allow you to cache images as desired. See the Example for a more complex scenario, which provides different layers of caching:

Disk Cache


You can provide a placeholder renderer to your AsyncImageView:

    initialFrame: .zero,
    renderer: Renderer.singleton.normalImageRenderer,
    placeholderRenderer: Renderer.singleton.placeholderImageRenderer

The image view will use the placeholder whenever its data is set to nil.

Error handling

AsyncImageView won't accept a renderer that can produce errors (this is checked at compile time). Because of that, you'll need to use .logAndIgnoreErrors.

Alternatively, you can use a different renderer (for example, LocalImageRenderer to load an image from disk instead) whenever there is an error:


Other features

More documentation will come for other features. In the mean time, feel free to explore the code to find more details:

  • LocalImageRenderer: load images from the bundle.
  • ImageInflaterRenderer: rasterize images.
  • ImageProcessingRenderer: asynchronously apply transformations to images.



If you use Carthage to manage your dependencies, simply add AsyncImageView to your Cartfile:

github "NachoSoto/AsyncImageView" ~> 5.0

If you use Carthage to build your dependencies, make sure you have added AsyncImageView.framework, ReactiveCocoa.framework, ReactiveSwift.framework, and Result.framework to the "Linked Frameworks and Libraries" section of your target, and have included them in your Carthage framework copying build phase.

Have a question?

If you need any help, feel free to send me a DM on Twitter, or open a GitHub issue.


Stars: 75

Used By

Total: 0


Swift 5.0 -

Swift 4.2 -

4.2 -

4.1 -

Swift 4.0 -

Swift 3.1 -

New Beginnings -

  • Dropped dependency on ReactiveCocoa, it only depends on ReactiveSwift now.

Swift 3 -

0.1 - Initial Release -