Kingfisher源码解析系列,因为水平有限,哪里有错,肯请不吝赐教git
本篇文章主要介绍Processor和CacheSerializer的基本定义和调用时机,以及利用两者扩展Kingfisher以支持webp格式的图片github
Kingfisher中Processor是一个协议,定义了对原始数据进行加工处理转换成UIImage的能力(Kingfisher缓存的是处理成功以后的UIImage,根据options的值来决定是否缓存原始数据)。 这里的原始数据是指ImageProcessItem,它是一个枚举类型。Processor和ImageProcessItem定义以下,都是特别简单web
public enum ImageProcessItem {
case image(KFCrossPlatformImage)
case data(Data)
}
public protocol ImageProcessor {
//标识符,在缓存的时候用到,用于区分原始数据和处理加工以后的数据的
var identifier: String { get }
//交给具体的实现类去实现,ImageProcessItem,最终返回一个UIImage
func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?
}
复制代码
若是你了解过Kingfisher,请尝试回答下这2个问题缓存
ImageProcessor.process在何时调用,在调用的时候会传递什么类型的数据?bash
Kingfisher中CacheSerializer定义了图片序列化和反序列化的能力,也是一个协议网络
public protocol CacheSerializer {
func data(with image: KFCrossPlatformImage, original: Data?) -> Data?
func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?
}
复制代码
func data(with image: KFCrossPlatformImage, original: Data?) -> Data?
把image序列化成data,以便写入文件func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?
把data反序列化为UIImageKingfisher自己是不支持webp格式的图片,可是能够利用Processor和CacheSerializer对Kingfisher进行扩展,让Kingfisher支持webP格式的图片ide
WebP 标准是 Google 定制的,迄今为止也只有 Google 发布的 libwebp 实现了该的编解码 。 因此这个库也是该格式的事实标准。post
所以要想支持webp格式的图片,须要依赖libwebp库,用来实现图片的编码和解码,对于这块的代码我是从SDWebImageWebPCoder复制过来的,而且去掉了对动图的支持和一些SD配置的代码,若是你对这块感兴趣,请参考源码,因为SD是OC写的,因此这部分我用的也是OC,最终给UIImage添加了一个分类,提供了下面2个方法fetch
@interface UIImage (WebP)
//序列化为Data
@property(nonatomic,strong,readonly,nullable) NSData *webPData;
//经过data反序列化为UIImage
+ (nullable instancetype)imageWithWebPData:(NSData *)webPdata;
+
@end
复制代码
在process判断item的类型,如果image则直接返回,如果data则反序列化为UIImageui
public struct WebPProcessor: ImageProcessor {
public static let `default` = WebPProcessor()
public let identifier = "WebPProcessor"
public init() {}
public func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
switch item {
case .image(let image):
return image
case .data(let data):
return UIImage(webPData: data)
}
}
}
复制代码
public struct WebPCacheSerializer: CacheSerializer {
public static let `default` = WebPCacheSerializer()
private init() {}
public func data(with image: KFCrossPlatformImage, original: Data?) -> Data? {
return image.webPData;
}
public func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
return UIImage(webPData: data);
}
}
复制代码
if let url = URL(string:"http://q21556z4z.bkt.clouddn.com/123.webp?e=1575537931&token=7n8bncOpnUSrN4mijeEAJRdVXnC-jm-mk5qTjKjR:L1_MWy3xugv9ct6PD294CHzwiSE=&attname=") {
imageView.kf.setImage(
with: url,
options: [.processor(WebPProcessor.default), .cacheSerializer(WebPCacheSerializer.default)]
)
}
复制代码
虽然说上面的代码都比较简单,可是我感受Kingfisher的这个设计真的挺好的,可扩展支持任意类型的图片,而且Processor是用来加工处理图片的,能作的还有其余方面,好比Kingfisher中提供了多种实现类,好比圆角的RoundCornerImageProcessor,显示高清图的DownsamplingImageProcessor,组装多种Processor的GeneralProcessor。 demo地址