目录
一、使用方式:
二、下载原理:
三、请求设置:
请求的默认设置方式通过上面的单例设置,单独每个请求的设置可以通过
四、缓存机制
五、下载设置
今年到新公司,发现公司用的kingfisher这个第三方库,和SDWebImage很类似,不过是swift版本的,就了解了下。
源码地址: https://github.com/onevcat/Kingfisher
我看的是swift4.0最新版
通过KingfisherManager单例对象调用。因为swift3以后大部分第三方调用普遍采用点方式,这个亦不例外,可以直接.kf调用单例。封装方式:
public final class Kingfisher {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
public protocol KingfisherCompatible {
associatedtype CompatibleType
var kf: CompatibleType { get }
}
public extension KingfisherCompatible {
public var kf: Kingfisher {
return Kingfisher(self)
}
}
extension Image: KingfisherCompatible { }
extension ImageView: KingfisherCompatible { }
extension Button: KingfisherCompatible { }
这样就可以实现image、Imageview、button的.kf调用,并且通过kf.base访问调用的对象实现封装。
通过扩展extension Kingfisher where Base: ImageView {}实现每个对象的自定义方法,方法内部self.base即当前imageView。
let url = URL.init(string: newValue)
self.imageView.kf.setImage(with: url)
基于kf作者imageView封装过后可以直接调用
KF是基于URLSession、URLSessionDelegate进行封装的,请求默认属性可以在appdeleget初始化是单例更改。例如:
KingfisherManager.shared.downloader.downloadTimeout = 12.0
更改超时时间
retrieveImage(with resource: Resource,
options: KingfisherOptionsInfo?,
progressBlock: DownloadProgressBlock?,
completionHandler: CompletionHandler?) -> RetrieveImageTask
单例方法调用的options设置,此外kf作者封装的也可以直接传参。
KingfisherOptionsInfo介绍:
case downloader(ImageDownloader)//获取更改session属性,设置请求
case transition(ImageTransition)//自定义动画
case downloadPriority(Float)//下载优先级(0-1)
case forceRefresh //每次请求忽略缓存,直接下载
case fromMemoryCacheOrRefresh//先取缓存再去文件,再去下载
forceTransition. //强制移动
cacheMemoryOnly //只从缓存读取,不读取本机沙盒图片
onlyFromCache//从缓存、沙盒读取,没有也不下载网络,显示placeholder
backgroundDecode//设置后,显示前在后台线程解码
case scaleFactor(CGFloat)。//自定义图片data -> Image缩放比例,不指定按屏幕2x\3x缩放
preloadAllAnimationData////预先加载data成图片缓存
case requestModifier(ImageDownloadRequestModifier)//改变请求 func modified(for request: URLRequest) -> URLRequest? //手动更改单个请求超时时间等一系列属性
case processor(ImageProcessor)//自定义da ta转图片样式
case cacheSerializer(CacheSerializer)//自定义缓存data 转图像样式
case keepCurrentImageWhileLoading //包含这个意味着placeHolder设置无效,没有直接用默认
case onlyLoadFirstFrame。//如果返回结果是.gif图,只取第一帧显示
cacheOriginalImage //设置后,同时缓存原始图片和下载后的图片
缓存处理主要在ImageCache类里面
kf缓存和sdwebimage一致,默认存储在domain文件夹,都是下载下来存在缓存和沙盒里面。下载时先去缓存取,取不到取沙盒取,沙盒取不到去网络下载
此外,kf里面,每次进入后台都会删除一周以前的图片(默认一周),然后文件按存储日期排序,删除到自定义最大沙盒存储量的一半(默认无限制)
可以更改的属性(更改方式参考二三部分):
maxMemoryCost //最大缓存量(默认无限制,收到内存警告直接清空)
pathExtension //沙盒后续拼接文件夹名称
maxCachePeriodInSecond. //清除多久前的图片,默认一周
maxDiskCacheSize //沙盒最大存储量,小于等于0表示无限制。默认无限制
ImageDownloader这个文件里面(设置参考二三部分)
downloadTimeout. //超时时间
trustedHosts。//信任的请求地址,和自己实现请求代理设置冲突,二选一
sessionConfiguration。//session配置设置
requestsUsePipelining //请求是否管道类型,是否按顺序下载,第一个下载完成在下载下张图片。默认false
delegate. //下载代理,kf已经封装在请求代码块里面,也可以自己全局代理封装处理
authenticationChallengeResponder //信任请求代理,和trustedHosts冲突二选一
fetchLoads //下载完成每个URL可能有多个处理方式,优先取这里的。
六、其他
kf内图片处理挺好的,这里注释下部分方式,喜欢的可以自己去看下,在Image.swift文件里
1、扩展类存储属性,黑魔法:
fileprivate(set) var animatedImageData: Data? {
get {
return objc_getAssociatedObject(base, &animatedImageDataKey) as? Data
}
set {
objc_setAssociatedObject(base, &animatedImageDataKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
2、public var normalized: Image //返回调整后的图片
3、static func animated(with data: Data, scale: CGFloat = 1.0, duration: TimeInterval = 0.0, preloadAll: Bool, onlyFirstFrame: Bool = false) -> Image? //GIF图data 转图片
4、static func image(data: Data, scale: CGFloat, preloadAllAnimationData: Bool, onlyFirstFrame: Bool) -> Image? //根据data生成图片,GIF图根据preloadAllAnimationData是否展示所有动画图片,onlyFirstFrame:是否只取GIF第一张图片 ,有调用上面的方法
5、public func image(withBlendMode blendMode: CGBlendMode, alpha: CGFloat = 1, backgroundColor: Color? = nil)-> Image。 //根据blendMode、透明度、背景色 调整图片
6、public func image(withRoundRadius radius: CGFloat, fit size: CGSize, roundingCorners corners: RectCorner = .all, backgroundColor: Color? = nil) -> Image ////切换到指定角度、大小、背景色
7、 public func resize(to size: CGSize) -> Image //改变图片大小
8、 public func resize(to size: CGSize, for contentMode: ContentMode) -> Image。//根据ContentMode和目标size更改图片大小。//aspectFit: 根据图片比缩小到size // aspectFill:根据图片比放大到size
9、public func crop(to size: CGSize, anchorOn anchor: CGPoint) -> Image //固定瞄点,缩小图片到指定size
10、public func blurred(withRadius radius: CGFloat) -> Image//根据角度模糊处理图片
11、public func overlaying(with color: Color, fraction: CGFloat) -> Image//图片添加overlay覆盖色fraction覆盖透明度
12、public func adjusted(brightness: CGFloat, contrast: CGFloat, saturation: CGFloat, inputEV: CGFloat) -> Image//图片亮度、饱和度、对比度修改 kCIInputEVKey不知道这个对应什么描述,喜欢的可以自己看下效果。
13、public func scaled(to scale: CGFloat) -> Image//缩放‘
14、
//图片格式确定。根据前8个字节对比图片类型
var imageFormat: ImageFormat {
var buffer = [UInt8](repeating: 0, count: 8)
(base as NSData).getBytes(&buffer, length: 8)
if buffer == ImageHeaderData.PNG {
return .PNG
} else if buffer[0] == ImageHeaderData.JPEG_SOI[0] &&
buffer[1] == ImageHeaderData.JPEG_SOI[1] &&
buffer[2] == ImageHeaderData.JPEG_IF[0]
{
return .JPEG
} else if buffer[0] == ImageHeaderData.GIF[0] &&
buffer[1] == ImageHeaderData.GIF[1] &&
buffer[2] == ImageHeaderData.GIF[2]
{
return .GIF
}
return .unknown
}