Kingfisher的基本使用(一)
序言
Kingfisher 是一个下载、缓存网络图片的轻量级纯swift库, 作者@王巍自称是受著名三方库SDWebImage激励所写,一年多以来,该库深受广大iOS之swift开发者所喜爱,目前被很多iOS开发者应用在app中。在swift中它真的是一个SDWebImage的升级版,作为swift开发者来说,为了摒弃Objective-C的风格,甚至“断绝”与Objective-C的关系,使工程更swift化,我们更希望更喜欢使用纯净的swift来开发自己的app。在此,也非常感谢@喵神给众多开发者提供了很大的便利,
为业界开发者所做的无私贡献。
github: [Kingfisher] (https://github.com/onevcat/Kingfisher)
特征
- 异步下载和缓存图片
- 基于
networking
的URLSession
, 提供基础的图片处理器和过滤器 - 内存和磁盘的多层缓存
- 可撤销组件,可根据需要分开地使用下载器和缓存系统
- 必要时可从缓存中读取并展示图片
- 扩展
UIImageView
、NSImage
、UIButton
来直接设置一个URL
图片 - 设置图片时,内置过渡动画
- 支持扩展图片处理和图片格式
先看一个Kingfisher的基本用法:从网络上设置一张基本的图片
let url = URL(string: "http://mvimg2.meitudata.com/55fe3d94efbc12843.jpg")
imageView.kf.setImage(with: url)
美女跃然屏上(模拟器截图)
![](https://img.haomeiwen.com/i1974698/ef2bc5bc16fb36c6.gif)
设置方式 2 :使用gif图作为加载菊花
let path = Bundle.main.path(forResource: "myImage", ofType: "gif")!
let data = try! Data(contentsOf: URL(fileURLWithPath: path))
imageView.kf.indicatorType = .image(imageData: data)
imageView.kf.setImage(with: url)
演示效果
![](https://img.haomeiwen.com/i1974698/54c9b66370cdb5fe.gif)
设置方式 3 :自定义菊花,遵循 Indicator
协议
let myIndicator = CustomIndicator()
imageView.kf.indicatorType = .custom(indicator: myIndicator)
imageView.kf.setImage(with: url)
struct CustomIndicator: Indicator {
var view: IndicatorView = UIView()
func startAnimatingView() {
view.isHidden = false
}
func stopAnimatingView() {
view.isHidden = true
}
init() {
view.backgroundColor = UIColor.magenta
}
}
诠释:Indicator是一个协议,如果我们要实现自定义菊花加载,只需要遵循这个协议即可,另外必须得说的是,
Indicator协议
中有一个属性viewCenter
我们不需要在遵循协议的时候去实现,因为喵神已经为我们提供了默认实现(我还因为这个问题在github上问过他,突然觉得好蠢...)
设置方式 4 : 根据实时下载图片的数据做进度条加载或者菊花加载(灵活,比例为:图片已下载数据 / 图片总数据)
imageView.kf.setImage(with: url, placeholder: nil, options: nil, progressBlock: { (receivedData, totolData) in
let percentage = (Float(receivedData) / Float(totolData)) * 100.0
print("downloading progress is: \(percentage)%")
// 这里用进度条或者绘制view都可以,然后根据 percentage% 表示进度就行了
}, completionHandler: nil)
设置过渡动画,渐变效果(图片下载结束后)
imageView.kf.setImage(with: url, placeholder: nil, options: [.transition(.fade(0.4))], progressBlock: nil, completionHandler: nil)
诠释: 在
Kingfisher
中,有一个options
, 我们可以做一些选择,Kingfisher里面目前包含了18种选择,在图片下载结束后,为了实现一些效果,我们可以实现上面的渐变效果,或者还有更多的翻滚效果! 但是Kingfisher
,上面的这个过渡动画值只是针对图片是从web下载时调用,如果是从内存或磁盘中取时是不会有这个效果的,虽然里面也有一个枚举值强制动画forceTransition
,但是似乎暂时作者还没有实现这个功能。
设置图片模糊效果
let processor = BlurImageProcessor(blurRadius: 25)
imageView.kf.setImage(with: url, placeholder: nil, options: [.processor(processor)], progressBlock: nil, completionHandler: nil)
![](https://img.haomeiwen.com/i1974698/255939651c342285.gif)
打印结果:
test
cacheCheckResult is CacheCheckResult(cached: true, cacheType: Optional(Kingfisher.CacheType.memory))
Image1 in disk cache is Optional(<UIImage: 0x600000281b80>, {2448, 3264})
Image2 in disk cache is Optional(<UIImage: 0x600000281cc0>, {2448, 3264})
image1 in memory cache is Optional(<UIImage: 0x600000280910>, {2448, 3264})
image2 in memory cache is Optional(<UIImage: 0x600000280910>, {2448, 3264})
image is Optional(<UIImage: 0x600000280910>, {2448, 3264})
cacheType is memory
分析: 从结果分析来看,但你使用
Kingfisher
来存储图片时,默认是存储在memory
和disk
; 第一次run, 先是从内存中获取图片(此时内存中和磁盘中都有缓存);若我们不卸载模拟器上的app
, 然后再次运行模拟器,也即是杀死进程,那么我们看到的将是从disk
中获取图片,因为在杀死进程后,内存中的缓存被清空(回收内存),只有磁盘中有缓存; 若接着再次获取缓存图片(不杀死进程),那么我们又看到是从memory
中获取到的图片,因为第一次从disk
中获取图片后,就会将disk
中的缓存图片放在内存中进行缓存,在不杀死进程的情况下,会直接从内存中获取!!!看一下下面的再次演示:
![](https://img.haomeiwen.com/i1974698/a0bf85c1a16cceca.gif)
当然,我们也可以直接指定是需要缓存到磁盘还是内存:
ImageCache.default.store(image, // 图片
original: data, // 原图片的data数据(Kingfisher推荐有,原因我后续有空会说)
forKey: "Specified_Keys", // 指定key
processorIdentifier: "", // 处理器标识符(使用处理器处理图片时,把这个标识传给它),标识会用来给 key 和 processor 的组合产生一个对应的key)
cacheSerializer: DefaultCacheSerializer.default, // 缓存序列化,这里默认
toDisk: false, // 是否缓存到disk(磁盘)
completionHandler: nil) // 完成回调
移除缓存图片
// 移除 key 为 Specified_Keys 的缓存图片,从内存和磁盘中都移除
ImageCache.default.removeImage(forKey: "Specified_Keys")
// 只清理内存中的缓存
ImageCache.default.removeImage(forKey: "Specified_Keys", processorIdentifier: "", fromDisk: false, completionHandler: nil)
限制(设置)磁盘的最大缓存(单位:字节)
// 设置磁盘的最大缓存容量为 10 M, 默认是0,表示无限制
ImageCache.default.maxDiskCacheSize = 10 * 1024 * 1024
获取(计算)当前磁盘缓存大小
ImageCache.default.calculateDiskCacheSize { (usedDiskCacheSize) in
print("usedDiskCacheSize is \(usedDiskCacheSize)")
}
手动清理缓存
- 立即清除内存缓存
ImageCache.default.clearMemoryCache()
- 清除磁盘缓存(异步操作)
ImageCache.default.clearDiskCache()
- 清除过期或超过磁盘缓存大小的缓存(异步操作)
ImageCache.default.cleanExpiredDiskCache()
注意:当你的
app
接收到内存警告(memory warning)的时候,Kingfisher
会净化内存缓存,也就是说,在需要的时候,Kingfisher
会主动清理一些已过期或者超过缓存尺寸大小的缓存,因此一般而言,没有必要自己手动去清理缓存,而这些清理缓存方法的存在主要在于以防你想要用户有更多对缓存进行操作的情况。比如有时候,有部分app
习惯在设置里面加一个清理缓存
的交互,为了方便,你可以根据需要调用这些手动清理缓存的方法。
设置存储在磁盘中的最长的缓存持续时间
// 5天后磁盘缓存将过期
ImageCache.default.maxCachePeriodInSecond = 5 * 24 * 60 * 60
注意:默认是一个周(即7天),单位是 秒。必须注意的是,如果设置成一个负值(比如 -1 )那么磁盘缓存决不会过期!
将一个默认路径扩展添加到每个缓存文件
// set a default path extension
KingfisherManager.shared.cache.pathExtension = "jpg"
注意:如果你是在macOS上使用
Kingfisher
并且想要添加拖放的操作的时候特别有用,大多数web输入字段不接受没有路径扩展的文件。什么意思呢?比如,你想在一个可拖进图片进行识别的表单中拖拽一张没有后缀.jpg
或png
的格式图片进去,实际上你操作的时候表单框是拒绝你的,你无法拖进去,如果你加了图片后缀识别名jpg
等后,就可以拖进去了,这就是这个方法的莫大好处,当然,如果你是iOS客户端开发,就忽略这个功能,因为作者说了,这个实在macOS
桌面应用上特别有用。
为默认图片下载器设置超时持续时间
// 设置成30秒,默认是15秒
ImageDownloader.default.downloadTimeout = 30
好了,到此为止,对于Kingfisher的基本使用介绍差不多了,后面还有很多方法,包括自定义下载器和缓存、取消下载任务或获取任务、在发送前修改请求等等 我们将在后面陆续介绍,对于喜欢Kingfisher
的小伙伴们也可以自己深入研究,基本的使用设置事实上很简单,但尽管如此,Kingfisher
中的很多地方还是很值得一探究竟的。
欢迎加入 iOS(swift)开发互助群:QQ群号:558179558, 相互讨论和学习!