原创 2017-06-06
Kingfisher是一个开源处理图片加载、缓存的开源库,它的灵感来源于SDWebImage(OC的一个框架,现在也提供了Swfit版本)。Kingfisher给你提供了一个使用纯Swift构建App的机会。
Kingfisher 有如下特性:
- 异步:使用Kingfisher操作的所有事件都是异步的,包括下载、检索、缓存,你无须担心UI线程阻塞问题
- 多级缓存:下载的图片可以缓存至内存和Disk,如果你重新下载相同的图片,多级缓存将会显著的加快你得到结果
- Mordern Framework:Kingfisher使用的是NSURLSession 以及最新的GCD,让你更方便的使用
- 可取消的任务:你可以取消你不想下载的任何任务
- 独立的组件:你可以单独的使用Downloader,也可以单独的使用Cache来创建你独立的多级缓存
- UI显示提升:在后台线程解压缩你的图片
- Extensions:提供了UIImageView与UIButton的扩展,方便你可以通过URL来显示你的图片
通过整理,我绘制了Kingfisher框架的一个大致思维导图,来帮助我更高效的学习理解该框架:
通过上述思维导图,我对Kingfisher的总结就一句话:通过KingfisherManager 来连接ImageDownloader与ImageCache来达到下载、多级缓存图片的目的,你可以设置你的下载配置以及缓存配置,并且还为UIKit提供了Extension来方便通过Resource显示图片。
如何使用Kingfisher
- Installation: 使用Pod方式引入到工程
platform :ios, '9.0'
target 'KingfisherDemo' do
use_frameworks!
pod 'Kingfisher', '~>3.9.1'
end
- 图片缓存ImageCache 使用
ImageChache 给你提供了多级缓存,可以使用内存、磁盘存储,还提供了存储、检索、清除图片、移除等操作,如果你需要监听到磁盘的变化可以通过KingfisherDidCleanDiskCacheNotification
添加通知。
// ImageCache,默认是
let cache = ImageCache.default
// 设置内存缓存的大小,默认是0 pixel表示no limit ,注意它是像素为单位,与我们平时的bytes不同
cache.maxMemoryCost = 10 * 1024 * 1024
// 磁盘缓存大小,默认0 bytes表示no limit (50 * 1024)
cache.maxDiskCacheSize = 50 * 1024 * 1024
// 设置缓存周期 (默认1 week)
cache.maxCachePeriodInSecond = 60 * 60 * 24 * 7
// 存储一张图片, Key 可用于后期检索资源、删除以及在删除时的一个通知参数
cache.store(UIImage(named: "test")!, forKey: "test")
// 删除
cache.removeImage(forKey: "test")
// 检索图片
let imgDisk = cache.retrieveImageInDiskCache(forKey: "test")
let imgMemo = cache.retrieveImageInMemoryCache(forKey: "test")
// 异步检索
cache.retrieveImage(forKey: "test", options: nil) { (_, _) in
}
// 清除
cache.clearDiskCache()
cache.clearMemoryCache()
cache.clearDiskCache {
}
// 清除过期缓存
cache.cleanExpiredDiskCache()
cache.cleanExpiredDiskCache {
}
cache.backgroundCleanExpiredDiskCache() // 后台清理,但不需要回调
// 判定图片是否存在
let cached = cache.isImageCached(forKey: "test")
// 监听数据移除
NotificationCenter.default.addObserver(self, selector: #selector(cleanDiskCache), name: NSNotification.Name.init("KingfisherDidCleanDiskCacheNotification"), object: nil)
- 图片加载ImageDownloader使用
从名字就可以很清楚的知道,这个类就是用来下载图片的,它为我们提供了一些头的设置(比如说你有些图片是需要认证用户才能下载的);安全设置:我们在下载图片时哪些Host是可信任的;下载超时设置;下载回调等。
let downloader = ImageDownloader.default
// 设置可信任的Host
let hosts: Set<String> = ["http://xxxxx.com", "http://#####.com"]
downloader.trustedHosts = hosts
// 设置sessionConfiguration
downloader.sessionConfiguration = URLSessionConfiguration.default
// 设置代理,详情参考 ImageDownloaderDelegate
downloader.delegate = self
// 下载超时设置
downloader.downloadTimeout = 20
// 下载图片
let retriveTask = downloader.downloadImage(with: URL(string: "http://xxx.com")!, retrieveImageTask: nil, options: nil, progressBlock: nil, completionHandler: {
(image, error, imageURL, originalData) in
})
// 取消下载
retriveTask?.cancel()
- 主控制器KingfisherManager使用
在上面的思维导图我已经提到过:KingfisherManager是连接ImageDownloader与ImageCache的,所以你可以通过manager得到 downloader与cache,并且还能改设置加载选项,当然你也可以设置其他的ImageDownloader与ImageCache到你的Manager。
let kfManager = KingfisherManager.shared
// 通过manager 获取cache
cache = kfManager.cache
// 通过manager 获取downloader
downloader = kfManager.downloader
// 设置options, 你可以设置你的newCache/newDownloader以及其他配置
kfManager.defaultOptions = [.targetCache(newCache), .downloader(newDownloader), .forceRefresh, .backgroundDecode, .onlyFromCache, .downloadPriority(1.0)]
// 检索
let resource = ImageResource(downloadURL: URL(string: "http://xxxx.com")!, cacheKey: "text")
let retriveImageTask = kfManager.retrieveImage(with: resource, options: nil, progressBlock: nil, completionHandler: {
(image, error, cacheType, imageURL) in
if error == nil {
print("检索图片成功")
} else {
print("检索图片失败")
}
})
retriveImageTask.cancel()
- UIXXX+Kingfisher使用
Kingfisher 提供了UIButton与UIImageView的扩展,使你可以通过直接设置图片URL来显示,两者用法差不多,以UIImageView为例:
// 设置网络图片
imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!))
imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!), placeholder: UIImage(named: "test"), options: nil, progressBlock: nil, completionHandler: nil)
// UIImageView 也可以设置取消加载 (两种方式)
imageView.kf.cancelDownloadTask()
let retriveImaeTask = imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!))
retriveImaeTask.cancel()
Kingfisher大致操作就这些,这与作者在设计该Framework时,希望它保持Slim思想一致,框架简洁,更多的使用或者其他Enums,Struts使用等,可以去Github查阅。这里我也提供了一个Kingfisher 示例代码