Kingfisher
A lightweight, pure-Swift library for downloading and caching images from the web.
Top Related Projects
Asynchronous image downloader with cache support as a UIImageView category
AlamofireImage is an image component library for Alamofire
Image loading system
Promises for Swift & ObjC.
A lightweight generic cache for iOS written in Swift with extra love for images.
Reactive Programming in Swift
Quick Overview
Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web. It provides a simple and efficient way to handle image loading in iOS, tvOS, macOS, and watchOS applications, with support for various image formats and caching strategies.
Pros
- Easy to use with a clean, chainable API
- Efficient memory and disk caching mechanisms
- Supports various image formats, including animated GIFs and WebP
- Extensible architecture allowing custom processors and caching systems
Cons
- May be overkill for simple image loading tasks
- Requires iOS 12.0+ or macOS 10.14+, which might be limiting for older projects
- Large library size compared to simpler alternatives
- Some advanced features may have a learning curve for beginners
Code Examples
- Basic image loading:
import Kingfisher
let imageView = UIImageView()
let url = URL(string: "https://example.com/image.jpg")
imageView.kf.setImage(with: url)
- Image loading with options:
imageView.kf.setImage(
with: url,
placeholder: UIImage(named: "placeholder"),
options: [
.transition(.fade(0.2)),
.cacheOriginalImage
]
)
- Prefetching images:
let urls = [URL(string: "https://example.com/image1.jpg")!,
URL(string: "https://example.com/image2.jpg")!]
ImagePrefetcher(urls: urls).start()
Getting Started
-
Install Kingfisher using Swift Package Manager, CocoaPods, or Carthage.
-
Import Kingfisher in your Swift file:
import Kingfisher
- Load an image into an image view:
let url = URL(string: "https://example.com/image.jpg")
imageView.kf.setImage(with: url)
- For more advanced usage, refer to the Kingfisher documentation for options, callbacks, and image processing features.
Competitor Comparisons
Asynchronous image downloader with cache support as a UIImageView category
Pros of SDWebImage
- Supports a wider range of image formats, including GIF, WebP, and APNG
- More extensive caching options, including disk and memory caching
- Longer history and larger community, potentially leading to better stability and support
Cons of SDWebImage
- Written in Objective-C, which may be less appealing for Swift-only projects
- Generally considered to have a more complex API compared to Kingfisher
- Slightly larger library size, which may impact app size
Code Comparison
SDWebImage:
imageView.sd_setImage(with: URL(string: "https://example.com/image.jpg"), placeholderImage: UIImage(named: "placeholder"))
Kingfisher:
imageView.kf.setImage(with: URL(string: "https://example.com/image.jpg"), placeholder: UIImage(named: "placeholder"))
Both libraries offer similar functionality for basic image loading, with Kingfisher's syntax being slightly more concise. SDWebImage provides more options for customization out of the box, while Kingfisher focuses on simplicity and Swift-native implementation.
When choosing between the two, consider factors such as your project's language (Swift vs Objective-C), required image formats, and specific caching needs. Kingfisher may be preferable for Swift-only projects seeking a lightweight solution, while SDWebImage might be better suited for projects requiring extensive format support and advanced caching options.
AlamofireImage is an image component library for Alamofire
Pros of AlamofireImage
- Integrated with Alamofire, providing seamless networking and image loading
- Supports advanced image transitions and filters
- Offers more granular control over image caching and processing
Cons of AlamofireImage
- Requires Alamofire as a dependency, which may increase app size
- Less frequently updated compared to Kingfisher
- Slightly steeper learning curve for developers new to Alamofire ecosystem
Code Comparison
Kingfisher:
let imageView = UIImageView()
imageView.kf.setImage(with: URL(string: "https://example.com/image.jpg"))
AlamofireImage:
let imageView = UIImageView()
imageView.af.setImage(withURL: URL(string: "https://example.com/image.jpg"))
Both libraries offer similar ease of use for basic image loading tasks. However, AlamofireImage provides more advanced features when used in conjunction with Alamofire's networking capabilities, while Kingfisher focuses on being a standalone image loading and caching solution.
Kingfisher is generally considered more lightweight and easier to integrate for projects that don't already use Alamofire. It also receives more frequent updates and has a larger community. On the other hand, AlamofireImage shines in projects that heavily rely on Alamofire for networking, offering tighter integration and advanced features specific to the Alamofire ecosystem.
Image loading system
Pros of Nuke
- Smaller codebase and faster compilation times
- More efficient memory usage, especially for large images
- Better support for progressive image loading
Cons of Nuke
- Smaller community and fewer third-party extensions
- Less comprehensive documentation compared to Kingfisher
- Fewer built-in image processing options
Code Comparison
Kingfisher:
let url = URL(string: "https://example.com/image.jpg")
imageView.kf.setImage(with: url)
Nuke:
let url = URL(string: "https://example.com/image.jpg")
Nuke.loadImage(with: url, into: imageView)
Both Kingfisher and Nuke are popular Swift libraries for downloading and caching images. Kingfisher offers a more extensive feature set and has a larger community, while Nuke focuses on performance and efficiency. The code usage is similar, with Kingfisher using a custom extension on UIImageView and Nuke using a static method. Choose Kingfisher for a more comprehensive solution with extensive documentation, or Nuke for a lightweight, performance-focused alternative.
Promises for Swift & ObjC.
Pros of PromiseKit
- Provides a robust asynchronous programming model for Swift and Objective-C
- Offers a wide range of extensions for popular iOS frameworks
- Simplifies complex asynchronous operations and error handling
Cons of PromiseKit
- Steeper learning curve for developers new to promise-based programming
- May introduce additional complexity for simple asynchronous tasks
- Requires careful management to avoid retain cycles and memory leaks
Code Comparison
PromiseKit:
firstly {
fetchUser()
}.then { user in
fetchAvatar(for: user)
}.done { avatar in
self.imageView.image = avatar
}.catch { error in
print("Error: \(error)")
}
Kingfisher:
let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url, placeholder: UIImage(named: "placeholder"),
options: [.transition(.fade(0.2))],
progressBlock: { receivedSize, totalSize in
print("\(receivedSize)/\(totalSize)")
},
completionHandler: { result in
switch result {
case .success(let value):
print("Image: \(value.image). Got from: \(value.cacheType)")
case .failure(let error):
print("Error: \(error)")
}
})
While PromiseKit focuses on general asynchronous programming, Kingfisher specializes in image downloading and caching. PromiseKit offers more flexibility for various asynchronous tasks, while Kingfisher provides a simpler API specifically for image handling.
A lightweight generic cache for iOS written in Swift with extra love for images.
Pros of HanekeSwift
- Lightweight and simple to use
- Built-in support for multiple cache types (memory, disk, and custom)
- Automatic cache eviction based on access time and memory pressure
Cons of HanekeSwift
- Less actively maintained compared to Kingfisher
- Fewer advanced features and customization options
- Smaller community and ecosystem
Code Comparison
HanekeSwift:
let imageView = UIImageView()
imageView.hnk_setImageFromURL(url)
Kingfisher:
let imageView = UIImageView()
imageView.kf.setImage(with: url)
Both libraries offer simple one-line methods for loading images from URLs into UIImageViews. However, Kingfisher provides more extensive options for customization and advanced features.
HanekeSwift is a good choice for projects that require a lightweight image caching solution with built-in support for multiple cache types. It's easy to use and has automatic cache management features.
Kingfisher, on the other hand, offers a more comprehensive set of features, active maintenance, and a larger community. It's better suited for projects that require advanced image loading and caching capabilities, as well as long-term support and updates.
Reactive Programming in Swift
Pros of RxSwift
- Comprehensive reactive programming framework for complex asynchronous operations
- Extensive ecosystem with many extensions and integrations
- Powerful operators for transforming and combining data streams
Cons of RxSwift
- Steeper learning curve due to its complexity and paradigm shift
- Potential for memory leaks if not used carefully (e.g., retain cycles)
- Larger codebase and increased app size compared to Kingfisher
Code Comparison
RxSwift example:
Observable.from([1, 2, 3, 4, 5])
.filter { $0 % 2 == 0 }
.map { $0 * 2 }
.subscribe(onNext: { print($0) })
Kingfisher example:
let url = URL(string: "https://example.com/image.jpg")
imageView.kf.setImage(with: url)
Summary
RxSwift is a powerful reactive programming framework for handling complex asynchronous operations, while Kingfisher is a lightweight library focused on image downloading and caching. RxSwift offers more flexibility and power for managing data streams and event-driven programming, but comes with a steeper learning curve. Kingfisher, on the other hand, provides a simple and efficient solution for image handling in iOS apps.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Kingfisher is a powerful, pure-Swift library for downloading and caching images from the web. It provides you a chance to use a pure-Swift way to work with remote images in your next app.
Features
- Asynchronous image downloading and caching.
- Loading image from either
URLSession
-based networking or local provided data. - Useful image processors and filters provided.
- Multiple-layer hybrid cache for both memory and disk.
- Fine control on cache behavior. Customizable expiration date and size limit.
- Cancelable downloading and auto-reusing previous downloaded content to improve performance.
- Independent components. Use the downloader, caching system, and image processors separately as you need.
- Prefetching images and showing them from the cache to boost your app.
- Extensions for
UIImageView
,NSImageView
,NSButton
,UIButton
,NSTextAttachment
,WKInterfaceImage
,TVMonogramView
andCPListItem
to directly set an image from a URL. - Built-in transition animation when setting images.
- Customizable placeholder and indicator while loading images.
- Extensible image processing and image format easily.
- Low Data Mode support.
- SwiftUI support.
- Swift 6 & Swift Concurrency (strict mode) prepared.
Kingfisher 101
The simplest use-case is setting an image to an image view with the UIImageView
extension:
import Kingfisher
let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url)
Kingfisher will download the image from url
, send it to both memory cache and disk cache, and display it in imageView
.
When you set it with the same URL later, the image will be retrieved from the cache and shown immediately.
It also works if you use SwiftUI:
var body: some View {
KFImage(URL(string: "https://example.com/image.png")!)
}
A More Advanced Example
With the powerful options, you can do hard tasks with Kingfisher in a simple way. For example, the code below:
- Downloads a high-resolution image.
- Downsamples it to match the image view size.
- Makes it round cornered with a given radius.
- Shows a system indicator and a placeholder image while downloading.
- When prepared, it animates the small thumbnail image with a "fade in" effect.
- The original large image is also cached to disk for later use, to get rid of downloading it again in a detail view.
- A console log is printed when the task finishes, either for success or failure.
let url = URL(string: "https://example.com/high_resolution_image.png")
let processor = DownsamplingImageProcessor(size: imageView.bounds.size)
|> RoundCornerImageProcessor(cornerRadius: 20)
imageView.kf.indicatorType = .activity
imageView.kf.setImage(
with: url,
placeholder: UIImage(named: "placeholderImage"),
options: [
.processor(processor),
.scaleFactor(UIScreen.main.scale),
.transition(.fade(1)),
.cacheOriginalImage
])
{
result in
switch result {
case .success(let value):
print("Task done for: \(value.source.url?.absoluteString ?? "")")
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
It is a common situation I can meet in my daily work. Think about how many lines you need to write without Kingfisher!
Method Chaining
If you are not a fan of the kf
extension, you can also prefer to use the KF
builder and chained the method
invocations. The code below is doing the same thing:
// Use `kf` extension
imageView.kf.setImage(
with: url,
placeholder: placeholderImage,
options: [
.processor(processor),
.loadDiskFileSynchronously,
.cacheOriginalImage,
.transition(.fade(0.25)),
.lowDataMode(.network(lowResolutionURL))
],
progressBlock: { receivedSize, totalSize in
// Progress updated
},
completionHandler: { result in
// Done
}
)
// Use `KF` builder
KF.url(url)
.placeholder(placeholderImage)
.setProcessor(processor)
.loadDiskFileSynchronously()
.cacheMemoryOnly()
.fade(duration: 0.25)
.lowDataModeSource(.network(lowResolutionURL))
.onProgress { receivedSize, totalSize in }
.onSuccess { result in }
.onFailure { error in }
.set(to: imageView)
And even better, if later you want to switch to SwiftUI, just change the KF
above to KFImage
, and you've done:
struct ContentView: View {
var body: some View {
KFImage.url(url)
.placeholder(placeholderImage)
.setProcessor(processor)
.loadDiskFileSynchronously()
.cacheMemoryOnly()
.fade(duration: 0.25)
.lowDataModeSource(.network(lowResolutionURL))
.onProgress { receivedSize, totalSize in }
.onSuccess { result in }
.onFailure { error in }
}
}
Requirements
Kingfisher 8.0
- (UIKit/AppKit) iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+ / visionOS 1.0+
- (SwiftUI) iOS 14.0+ / macOS 11.0+ / tvOS 14.0+ / watchOS 7.0+ / visionOS 1.0+
- Swift 5.0+
Kingfisher 7.0
- (UIKit/AppKit) iOS 12.0+ / macOS 10.14+ / tvOS 12.0+ / watchOS 5.0+ / visionOS 1.0+
- (SwiftUI) iOS 14.0+ / macOS 11.0+ / tvOS 14.0+ / watchOS 7.0+ / visionOS 1.0+
- Swift 5.0+
Installation
A detailed guide for installation can be found in Installation Guide.
Swift Package Manager
- File > Swift Packages > Add Package Dependency
- Add
https://github.com/onevcat/Kingfisher.git
- Select "Up to Next Major" with "7.0.0"
CocoaPods
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
use_frameworks!
target 'MyApp' do
pod 'Kingfisher', '~> 7.0'
end
Pre-built Framework
- Open the release page, download the latest version of Kingfisher from the assets section.
- Drag the
Kingfisher.xcframework
into your project and add it to the target (usually the app target). - Select your target, in the "General" Tab, find the "Frameworks, Libraries, and Embedded Content" section, set the
Embed Without Signing
to Kingfisher.
Migrating
Kingfisher 8.0 Migration Kingfisher 7.0 Migration
If you are using an even earlier version, see the guides below to know the steps for migrating.
Next Steps
Check the documentation and tutorials:
Other
Future of Kingfisher
I want to keep Kingfisher lightweight. This framework focuses on providing a simple solution for downloading and caching images. This doesnât mean the framework canât be improved. Kingfisher is far from perfect, so necessary and useful updates will be made to make it better.
Developments and Tests
Any contributing and pull requests are warmly welcome. However, before you plan to implement some features or try to fix an uncertain issue, it is recommended to open a discussion first. It would be appreciated if your pull requests could build with all tests green. :)
About the logo
The logo of Kingfisher is inspired by Tangram (ä¸å·§æ¿), a dissection puzzle consisting of seven flat shapes from China. I believe she's a kingfisher bird instead of a swift, but someone insists that she is a pigeon. I guess I should give her a name. Hi, guys, do you have any suggestions?
Contact
Follow and contact me on Twitter or Sina Weibo. If you find an issue, open a ticket. Pull requests are warmly welcome as well.
Backers & Sponsors
Open-source projects cannot live long without your help. If you find Kingfisher to be useful, please consider supporting this project by becoming a sponsor. Your user icon or company logo shows up on my blog with a link to your home page.
Become a sponsor through GitHub Sponsors. :heart:
Special thanks to:
License
Kingfisher is released under the MIT license. See LICENSE for details.
Top Related Projects
Asynchronous image downloader with cache support as a UIImageView category
AlamofireImage is an image component library for Alamofire
Image loading system
Promises for Swift & ObjC.
A lightweight generic cache for iOS written in Swift with extra love for images.
Reactive Programming in Swift
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot