Kingfisher 是一个用于在 iOS、macOS 和 watchOS 上加载和缓存图像的库,使用纯 Swift 编写。根据 官方仓库,该库完全支持 Swift Concurrency、Combine 和 SwiftUI,以及自动两级缓存。Kingfisher 以其类型安全的 API 和与 Swift 项目的轻松集成而闻名。
要点
Kingfisher — 一个用于在 Apple 平台上异步加载和缓存图像的库,完全用 Swift 编写。该库的作者是 Wei Wang(onevcat)。Kingfisher 提供了一套工具,用于从网络加载图像,具有自动缓存、转换和对现代 Swift 技术(async/await、Combine、Sendable)的支持。
该库在 GitHub 上拥有超过 23,000 颗星,并用于 Telegram、Snapchat 和 Dropbox 等应用中。Kingfisher 支持 GIF、APNG、HEIF 和所有标准图像格式。每个请求都返回类型安全的 Result
Kingfisher 的架构基于三个主要组件:Manager(加载管理器)、Cache(两级缓存)和 Processor(转换)。这些组件通过协议连接,允许在不更改依赖关系的情况下替换任何部分。
KingfisherManager — 协调图像加载、缓存和处理的中央类。它包含对 ImageCache 和 ImageDownloader 的引用,并提供统一的 retrieveImage 方法,在通过所有阶段后返回准备好的图像。
在调用 retrieveImage 时,Manager 首先检查内存缓存 — 带有 UIImage 的 NSCache,其中的键由源 URL 和 CacheSerializer 构成。如果找到图像,立即返回。如果未找到,则检查磁盘缓存 — 从文件系统读取并通过 serializer 解密。如果磁盘缓存为空,则通过 ImageDownloader 执行网络请求,结果被解码、转换并保存到两个缓存级别。
从 7.0 版本开始,Kingfisher 完全支持 async/await。retrieveImage 方法可作为异步函数使用,无需完成块即可直接返回 Result。这允许在现代 Swift 架构中使用 Structured Concurrency 进行库操作。
Kingfisher 分为多个模块,每个模块解决自己的任务。这种划分简化了组件的测试和替换。
KingfisherManager — 结合加载、缓存和处理器的外观。默认使用单例 KingfisherManager.shared,但可以为隔离场景(例如单元测试)创建具有自定义设置的单独实例。
ImageCache — 两级缓存,内存和磁盘具有单独的设置。内存缓存没有对象数量限制,但在内存不足时由系统清除。磁盘缓存将文件存储在目录中,具有 TTL 设置(默认 7 天)、大小限制(默认 0 — 无限制)和自动清除。
ImageProcessor — 具有单个方法 process(item:options:) 的协议,返回处理后的图像。内置实现:ResizingImageProcessor(调整大小)、RoundCornerImageProcessor(圆角)、BlurImageProcessor(高斯模糊)、OverlayImageProcessor(叠加颜色)。处理器可通过 |> 运算符组合。
Kingfisher 的缓存架构基于 write-through 原则:数据同时写入两个级别,读取从最快的级别 — 内存开始。缓存键是删除查询参数后的图像绝对 URL。
| 参数 | 内存缓存 | 磁盘缓存 |
|---|---|---|
| 存储 | NSCache(RAM) | 文件系统(SSD) |
| 格式 | UIImage(已解码) | Data(已压缩,通过 serializer) |
| 清除 | UIApplication.didReceiveMemoryWarningNotification | TTL + 超出限制 |
| 序列化 | 不需要 | CacheSerializer(默认 PNG/JPEG) |
| 线程安全 | 是(同步访问) | 是(IO 队列 + 屏障) |
对于管理磁盘缓存大小,使用按最后访问日期排序计算文件总大小。当超出限制时,删除具有最早访问日期的文件,直到大小降至限制的 50% 以下。TTL 清除在缓存初始化和每次调用 cleanExpired 时发生。
Kingfisher 提供了多个加载图像的接口:UIImageView 扩展、单独的管理器和 SwiftUI 视图。
kf — UIImageView 上的命名空间属性,提供 setImage、cancelDownload 方法和加载指示器。setImage 方法接受 URLSource 和可选的 Options 参数及 completionHandler。
import Kingfisher
imageView.kf.setImage(
with: URL(string: "https://example.com/image.jpg"),
placeholder: UIImage(named: "placeholder"),
options: [
.processor(RoundCornerImageProcessor(radius: .point(12))),
.transition(.fade(0.3)),
.cacheMemoryOnly
],
progressBlock: { receivedSize, totalSize in
print("已加载 \(receivedSize) / \(totalSize)")
}
)
该方法返回 DownloadTask,支持通过 cancel 取消和跟踪进度。在内部,setImage 调用 KingfisherManager.shared.retrieveImage,自动将 ImageView 确定为 Target。
从 Kingfisher 7.0 开始,setImage 方法在异步版本中可用。这允许将图像加载集成到 Swift Structured Concurrency 中,无需回调。
func loadAvatar() async {
do {
let result = try await imageView.kf.setImage(
with: url,
options: [.processor(ResizingImageProcessor(
targetSize: CGSize(width: 100, height: 100)
))]
)
// result.image 包含 UIImage
} catch {
print("失败: \(error)")
}
}
KFImage — SwiftUI 视图,类似于 iOS 15 的 AsyncImage,但具有 Kingfisher 缓存的完整支持。该视图自动使用 KingfisherManager.shared,但通过 .configure 修改器支持自定义管理器。
struct AvatarView: View {
let url: URL
var body: some View {
KFImage(url)
.placeholder { ProgressView() }
.resizable()
.fade(duration: 0.25)
.forceTransition()
.frame(width: 80, height: 80)
.cornerRadius(40)
}
}
Kingfisher 提供内置指示器系统来显示图像加载进度。IndicatorType — 包含三个变体的枚举:.activity(UIActivityIndicatorView)、.progress(UIProgressView)和 .custom(Indicator 协议的自定义实现)。指示器在加载期间自动显示在 ImageView 上,完成后隐藏。
对于自定义指示器,需要实现 Indicator 协议,包含 startAnimatingView() 和 stopAnimatingView() 方法。这允许使用混合解决方案:带有 shimmer 动画的骨架、带有逐渐显示的占位图像或带有透明度动画的标志。Kingfisher 还支持通过 KingfisherManager.shared.defaultOptions 全局设置指示器。
在 iOS 平台上,Kingfisher 和 SDWebImage 是两个主导的图像加载库。它们之间的选择取决于项目语言、性能要求和生态系统。
| 标准 | Kingfisher | SDWebImage |
|---|---|---|
| 语言 | Swift(100%) | Objective-C + Swift |
| Async/Await | 原生支持 | 通过包装器 |
| Combine | 内置发布者 | 否 |
| Sendable | 支持 | 有限 |
| 类型安全 | 完全(Result 类型) | 通过 Any? |
| ImageProcessor | 通过 |> 组合 | 通过 && 转换 |
| 大小 | ~900 KB | ~1.2 MB |
| GitHub 星标 | 23,000+ | 25,000+ |
Kingfisher 的主要优势在于其 Swift-first 架构:完全支持 async/await、Combine Publishers、Sendable 和 Result 类型。SDWebImage 凭借更广泛的插件生态系统(WebP、SVG、MapKit)和对 Objective-C 的支持保持领先地位。
Kingfisher 通过 Swift Package Manager、CocoaPods 或 Carthage 安装。安装后,只需导入模块并调用任何加载方法即可 — 该库无需额外配置即可使用。
// Swift Package Manager (Package.swift)
dependencies: [
.package(
url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"
)
]
// CocoaPods (Podfile)
pod 'Kingfisher', '~> 7.12'
对于自定义全局设置,使用 KingfisherManager.shared。可以更改加载器超时、缓存策略和默认处理器。以下是 500 MB 缓存配置示例,TTL 为 14 天。
let cache = ImageCache(name: "custom")
cache.memoryStorage.config.totalCostLimit = 100 * 1024 * 1024
cache.diskStorage.config.sizeLimit = 500 * 1024 * 1024
cache.diskStorage.config.expiration = .days(14)
KingfisherManager.shared.cache = cache
ImageDownloader 也通过管理器配置:可以设置具有超时、标头和缓存策略的自定义 URLSessionConfiguration。要监视进度,可使用 KFIndicator 模块,支持 ActivityIndicator、ProgressView 和自定义指示器。
常见问题
Kingfisher — 用于 iOS 的图像加载库,使用纯 Swift 编写。它用于从网络异步加载、缓存和转换图像,完全集成到 SwiftUI、UIKit 和现代 Swift 技术中。
在 Xcode 中通过 File → Add Packages 添加 https://github.com/onevcat/Kingfisher.git 包,版本从 7.12.0 开始。或者在 Package.swift 中指定依赖关系,参数 from: “7.12.0”。安装后,导入 Kingfisher 模块。
Kingfisher 支持 JPEG、PNG、GIF、APNG、HEIF 和 WebP。所有格式都通过系统框架(ImageIO、CoreGraphics)解码。GIF 通过 CGImageSource 支持,具有渐进加载和动画功能。
Kingfisher 使用纯 Swift 编写,完全支持 async/await、Combine 和 Sendable。它提供类型安全的 Result API 和通过协议的模块化架构,简化了组件替换和测试。
要清除内存缓存,调用 KingfisherManager.shared.cache.clearMemoryCache()。对于磁盘缓存,使用 clearDiskCache()。仅删除过期文件 — cleanExpiredDiskCache()。缓存大小通过 cache.calculateDiskStorageSize() 检查。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。