Kingfisher: thư viện cache ảnh cho Swift
Kingfisher làm tốt đúng một việc: tải, cache và hiển thị ảnh từ xa trong app Swift mà không cần kéo theo tương tác Objective-C hay một thư viện network riêng. Downloader, cache và processor dùng độc lập được, cùng một builder API dùng chung cho UIKit và SwiftUI. Nó đáng dùng khi cần nhiều hơn cache kiểu dictionary tự chế — riêng hai processor downsampling và bo góc đã tiết kiệm công viết Core Graphics thủ công.
Kingfisher là gì?
Kingfisher là thư viện thuần Swift để tải và cache ảnh từ mạng, dành cho iOS, macOS, tvOS, watchOS và visionOS. Nó thêm extension `kf` cho UIImageView, NSImageView và một số view UIKit/AppKit khác, cùng view `KFImage` cho SwiftUI, cả hai dùng chung một lớp cache nhiều tầng gồm memory và disk. Các lượt tải có thể huỷ và sẽ tái dùng nội dung đã tải trước đó thay vì tải lại cùng một URL.
Tính năng chính của Kingfisher
- ✓Cache hai tầng hybrid, tách riêng lớp memory và disk, kèm thời hạn hết hạn và giới hạn dung lượng có thể cấu hình.
- ✓Async cache probing tùy chọn bật trong `KingfisherManager` để việc kiểm tra disk cache không chặn thread gọi.
- ✓Các image processor dựng sẵn, gồm processor downsampling và bo góc, nối chuỗi được bằng operator `|>`.
- ✓Các thành phần độc lập: downloader, cache và processor hoạt động riêng lẻ được, ngoài phạm vi extension `kf`/`KFImage`.
- ✓Download có thể huỷ và tái dùng nội dung đã tải trước đó thay vì tải lại cùng URL.
- ✓Extension trải khắp UIImageView, NSImageView, NSButton, UIButton, WKInterfaceImage, TVMonogramView và CPListItem.
- ✓Hỗ trợ SwiftUI qua `KFImage`, cùng khả năng sẵn sàng cho Swift 6 và strict-concurrency.
- ✓Tải và cache cho Live Photo, cùng hỗ trợ Low Data Mode cho mạng hạn chế.
Cài đặt Kingfisher vào dự án
Kingfisher cài qua Swift Package Manager: trong Xcode, chọn File > Swift Packages > Add Package Dependency, thêm `https://github.com/onevcat/Kingfisher.git`, rồi chọn rule "Up to Next Major" với "8.0.0". CocoaPods cũng dùng được: ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '13.0' use_frameworks! target 'MyApp' do pod 'Kingfisher', '~> 8.0' end ``` Còn có lựa chọn dùng framework dựng sẵn: tải `Kingfisher.xcframework` từ phần assets của trang release trên GitHub, kéo vào project, thêm vào target của app, rồi trong mục "Frameworks, Libraries, and Embedded Content" của target đặt thành "Embed Without Signing". Kingfisher 8.0 cần iOS 13.0+/macOS 10.15+/tvOS 13.0+/watchOS 6.0+/visionOS 1.0+ cho extension UIKit/AppKit, iOS 14.0+/macOS 11.0+/tvOS 14.0+/watchOS 7.0+/visionOS 1.0+ cho view `KFImage` của SwiftUI, và Swift 5.9+.
Tải ảnh với Kingfisher: ví dụ UIKit và SwiftUI
Cách gọi đơn giản nhất là qua extension UIKit: ```swift import Kingfisher let url = URL(string: "https://example.com/image.png") imageView.kf.setImage(with: url) ``` Kingfisher tải ảnh, ghi vào cả cache memory và disk, rồi hiển thị trong `imageView`; đặt lại cùng URL lần sau sẽ lấy từ cache thay vì tải lại. Bản tương đương cho SwiftUI là `KFImage`: ```swift var body: some View { KFImage(URL(string: "https://example.com/image.png")!) } ``` Với màn hình thật, bạn thường sẽ nối chuỗi processor. Đoạn code sau downsample một ảnh độ phân giải cao vừa khung view, bo góc, và hiển thị indicator cùng placeholder trong lúc tải: ```swift 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)") } } ``` Nếu không muốn dùng extension `kf`, builder `KF` nối cùng các option đó dưới dạng method call và kết thúc bằng `.set(to: imageView)`. Đổi `KF` thành `KFImage` là chuỗi y hệt chạy được trên SwiftUI.
Vì sao developer chọn Kingfisher
- ✓Chỉ là một dependency thuần Swift duy nhất, không phải bảo trì bridging header Objective-C nào.
- ✓Downloader, cache và processor là các thành phần độc lập, dùng được cả ngoài phạm vi extension `kf`/`KFImage`.
- ✓Builder API `KF`/`KFImage` giống nhau giữa UIKit và SwiftUI, nên đổi màn hình vẫn giữ nguyên chuỗi processor.
- ✓Hành vi cache — thời hạn hết hạn, giới hạn dung lượng — cấu hình trực tiếp được thay vì cố định.
- ✓Processor downsampling và bo góc có sẵn, khỏi cần thêm một thư viện xử lý ảnh riêng.
Hạn chế của Kingfisher
- △Cài qua framework dựng sẵn nghĩa là phải tự kéo file framework vào project và đặt "Embed Without Signing" bằng tay — nhiều bước hơn hẳn một dòng thêm qua SPM.
- △Việc chỉnh dung lượng và thời hạn cache phải làm thủ công, không tự động.
- △`KFImage` của SwiftUI cần phiên bản OS mới hơn (iOS 14.0+) so với extension `kf` của UIKit (iOS 13.0+ ở bản 8.0), nên project pha trộn UIKit/SwiftUI phải theo dõi hai mốc yêu cầu khác nhau.
- △Yêu cầu tính năng mới được đề nghị mở discussion trên GitHub trước khi gửi pull request, có thể làm chậm việc đóng góp.
Lựa chọn thay thế Kingfisher
Câu hỏi thường gặp về Kingfisher
Kingfisher phát hành theo giấy phép MIT, cho phép dùng thương mại, chỉnh sửa và phân phối lại mà không phải trả phí bản quyền, đúng như ghi trong file LICENSE của project.
Kingfisher hỗ trợ cả hai: extension `kf` bao phủ các view UIKit và AppKit như UIImageView, NSImageView, còn view `KFImage` cung cấp cùng khả năng tải và cache ảnh đó cho SwiftUI.
Kingfisher cài qua File > Swift Packages > Add Package Dependency trong Xcode, thêm `https://github.com/onevcat/Kingfisher.git` rồi chọn rule "Up to Next Major" với phiên bản "8.0.0".
Kingfisher 8.0 cần iOS 13.0+ và macOS 10.15+ cho extension UIKit/AppKit, còn iOS 14.0+ và macOS 11.0+ cho view `KFImage` của SwiftUI, theo đúng yêu cầu mà project công bố.
Kingfisher nối được `DownsamplingImageProcessor` với `RoundCornerImageProcessor` bằng operator `|>`, downsample ảnh gốc vừa khung view và bo góc trong đúng một bước xử lý.
Kingfisher viết bằng thuần Swift với view SwiftUI riêng là `KFImage`, trong khi SDWebImage có gốc Objective-C. Ngoài khác biệt ngôn ngữ đó, README không đưa ra bảng so sánh tính năng chi tiết nào.
Vấn đề Kingfisher giải quyết
Developer iOS và macOS tự tải ảnh từ xa thường phải viết lại đúng logic download qua URLSession, cache memory/disk và huỷ request ở mỗi project, rồi tự thêm phần bo góc hay downsampling bằng Core Graphics. Kingfisher gói sẵn tổ hợp đó — tải bất đồng bộ, cache hai lớp với thời hạn và giới hạn dung lượng có thể cấu hình, cùng chuỗi processor nối được — thành một dependency duy nhất, thay vì để mỗi app tự dựng lại từ một lệnh URLSession trần.
Trường hợp sử dụng tốt nhất
- •Đổ ảnh thumbnail từ xa vào table view hay collection view mà không phải tự viết logic download và cache.
- •Tải một ảnh chi tiết độ phân giải cao, downsample và bo góc vừa khung view, trong khi bản gốc vẫn được cache riêng.
- •Prefetch trước danh sách URL ảnh trước khi người dùng scroll tới, để cell hiển thị ảnh đã cache sẵn.
- •Thêm view ảnh từ xa vào màn hình SwiftUI qua `KFImage` thay vì tự viết wrapper `AsyncImage`.
- •Tải và cache asset Live Photo song song với ảnh tĩnh thông thường.
Ai nên dùng — và ai nên bỏ qua
Nên thử Kingfisher nếu bạn đang làm app iOS, macOS, tvOS, watchOS hay visionOS bằng Swift và cần tải ảnh từ xa có cache thật sự — hai lớp memory và disk với thời hạn cùng giới hạn dung lượng, cộng thêm processor downsampling và bo góc sẵn để nối chuỗi. Nó cũng hợp với team dựng cùng một màn hình cho cả UIKit lẫn SwiftUI, vì builder API dùng lại được. Bỏ qua nếu app của bạn thiên về Objective-C và chưa có kế hoạch bắc cầu sang Swift, nếu bạn đã gắn chặt với định dạng cache của SDWebImage, hoặc nếu chỉ cần tải mỗi một icon placeholder thì cả một lớp cache đầy đủ là thừa.
Repo liên quan
Muốn nghe thêm một ý kiến về Kingfisher?
Hỏi một AI đọc được trang này — một cú bấm là có ngay nhận định về Kingfisher.
