Skip to content

SwiftUI Support

onevcat edited this page Jan 3, 2021 · 5 revisions

Kingfisher itself is a combination of image downloader, cache layer and some extensions of UI elements.

The image downloader and cache layer is platform independency, so you can easily reuse in a SwiftUI app. From version 5.8.0, we added support to load an image in SwiftUI world: by providing a KFImage type to simplify the async image setting tasks. It conforms SwiftUI.View so you can integrate it to your SwiftUI app without effort. Behind the scene, it is driven by the powerful Kingfisher framework.

The same as SwiftUI, the SwiftUI part of Kingfisher is still in its early age. Please feel free to try and give any feedback!

Installation

No additional installation is required if you are using Kingfisher version 6.

SwiftUI support in Kingfisher v5

If you are still in version 5, in general, you can follow the steps in the Install Kingfisher guide. Choose the way you like, but with some small modification.

Swift Package Manager

Instead of adding Kingfisher to your project, you need to add KingfisherSwiftUI in the final step.

CocoaPods

SwiftUI support is provided in a sub-spec. So instead of specifying pod 'Kingfisher', you need pod 'Kingfisher/SwiftUI'.

Carthage

Both Kingfisher and KingfisherSwiftUI will be built when you run carthage update. You need to drag and add both frameworks to your project. Also remember to add both Kingfisher.framework and KingfisherSwiftUI.framework to the "Input Files" and "Output Files".

Using KFImage

Basic

KFImage wraps core features of Kingfisher to a Swift compatible View. Using KFImage is simple:

import SwiftUI
import Kingfisher

struct ContentView: View {
    let url = URL(
        string: "https://github.com/onevcat/Kingfisher/blob/master/images/kingfisher-1.jpg?raw=true"
    )
    var body: some View {
        KFImage(url)
    }
}

The code above will download the target url when it is going to appear on screen, and displays it in a SwiftUI.Image internally. At the same time, it stores the downloaded image in both memory cache and disk cache. When you set the same URL with KFImage, it will be loaded from the cache.

KFImage provides similar modifiers as SwiftUI.Image. Normally, you may want to specify a frame for the image:

KFImage(url)
    .resizable()
    .frame(width: 128, height: 128)

Or some modifiers from SwiftUI.View:

KFImage(url)
    .resizable()
    .frame(width: 128, height: 128)
    .cornerRadius(20)
    .shadow(radius: 5)

Configure KFImage

Besides of general view modifiers, KFImage also supports some others. It helps to give you a chance to react life cycles and do customization:

KFImage(url)
    .placeholder {
        // Placeholder while downloading.
        Image(systemName: "arrow.2.circlepath.circle")
            .font(.largeTitle)
            .opacity(0.3)
    }
    .retry(maxCount: 3, interval: .seconds(5))
    .onSuccess { r in
        // r: RetrieveImageResult
        print("success: \(r)")
    }
    .onFailure { e in
        // e: KingfisherError
        print("failure: \(e)")
    }

In List Cell

Loading an image in a list cell is a so common operation. It would be a waste if a cell is already out of screen, but the loading is not done yet. You can use .cancelOnDisappear to cancel any on-going download tasks automatically:

List {
    ForEach(0..<10) { i in
        KFImage(self.urls[i])
            .cancelOnDisappear(true)
}

Other Tips

Load from any Source

Besides of URL, KFImage accepts any original Source as its input. That means you can use customize cache key or load from an image data provider.

var resource: Resource {
    ImageResource(downloadURL: self.url!, cacheKey: "my_cache_key")
}

KFImage(source: .network(resource))

Options

Most of the Kingfisher options (but not all) are still valid in KFImage. Call the available methods from KFOptionSetter extensions to apply them to a KFImage:

KFImage(url)
    .downsampling(size: CGSize(width: 50, height: 50))
    .retry(maxCount: 3, interval: .seconds(5))
    .cacheOriginalImage()
    // etc.

Your knowledge of Kingfisher under UIKit/AppKit also applies to KFImage type. So remember to read the Cheat Sheet of Kingfisher!