最近 swift 又升级,我原本的 app 支持版本是到 iOS 9,
而 iOS 10 是 16年发布的,3年时间高中都快读完了,
发现不少 cocoapods 的库最新版本已经从 iOS 10 起跳支持
比如我们这篇的主角 Kingfisher 七巧板
猫大,onevcat大神所写,感谢大神的无私分享,
从swift面世至今,Kingfisher 感觉就是 oc时代的 SDWebImage
图片下载的江湖地位无可替代,4.0 之前 api 基本相同并兼容,
就算是 swift 大版本更新,老项目改改参数就能继续用
不过这次更新5以后,简直就是大换血,偏偏在网上找不到中文的文档
经过仔细看完wiki后,这里做个笔录,方便自己也方便后来人
随意转载,记得注明出处便可
如果是最基本的使用,那和以前一样,直接开箱可用
这里我直接把它做成了 UIImageView的扩展
extension UIImageView {
func ZImg(_ link : String ) {
self.kf.indicatorType = .activity
guard let nurl = URL(string: url) else {print("无图片", url); return }
let option : KingfisherOptionsInfo = [
.backgroundDecode, //后台解码 gif
.onlyLoadFirstFrame, //gif 只读第一帧
// .fromMemoryCacheOrRefresh //如果设置,Kingfisher会尝试从内存缓存中首先检索图像。 如果图像不在内存缓存中,则会忽略磁盘缓存,但是会再次从网络下载图像
]
self.kf.setImage(with: nurl, options: option)
}
}
用的时候直接 专门的imageView.ZImg( 图片地址 ),就可以正常使用
但如果是要获得下载完成回调的情况,几乎以前的写法就完全改完了
func ZImgWithCallback(_ url : String, completion:@escaping (UIImage?) ->Void) {
self.kf.indicatorType = .activity
self.kf.setImage(
with: URL(string: url),
placeholder: nil,
options: [
.scaleFactor(UIScreen.main.scale),
.transition(.fade(1)),
.cacheOriginalImage
]
) { result in
switch result {
case .success(let value):
// print("Task done for: \(value.source.url?.absoluteString ?? "")")
completion(value.image)
case .failure(let error):
print("ZImgWithCallback Job failed: \(error.localizedDescription)")
}
}
}
这样就是带有回调了,但会常出现下载文件差别的错误,不过基本可以不理,可以用这个方法判断图片是否存在
let is404 = error.isInvalidResponseStatusCode(404) //true就是404错误,图片不存在
最终写出一个带下载进度条的版本
func ZImgWithProgressAndCallback(_ url : String,
completion:@escaping (UIImage?) ->Void) {
// let viewsize = CGSize(width: 0.WD, height: 0.WH / 5)
// let processor = DownsamplingImageProcessor(size: viewsize)
// >> RoundCornerImageProcessor(cornerRadius: 0)
// let processor = OverlayImageProcessor(overlay: .red, fraction: 0.7)
self.kf.indicatorType = .activity
self.kf.setImage(
with: URL(string: url),
placeholder: nil, //UIImage(named: "placeholderImage"),
options: [
// .processor(DefaultImageProcessor.default), //后期滤镜
.scaleFactor(UIScreen.main.scale),
// .transition(.fade(1)),
.cacheOriginalImage
],
// 下载流程
progressBlock: { receivedSize, totalSize in
let percentage = (Float(receivedSize) / Float(totalSize)) // * 100.0
//直接当前页面处理下载进度条
self.setProgressView( percentage )
}
) { result in
switch result {
case .success(let value):
// print("Task done for: \(value.source.url?.absoluteString ?? "")")
completion(value.image)
case .failure(let error):
// print("Job failed: \(error)") //其他错误不管
let is404 = error.isInvalidResponseStatusCode(404)
if(is404){
ZAlertInfo("图片不存在", dismissTime: 2) //自己的警告方法
}
}
}
} //ZImgWithProgressAndCallback
而下载进度条的方法是这样
func setProgressView(_ progress: Float){
func getPview() -> UIProgressView{
// print("读取view")
var progressView: UIProgressView? = self.viewWithTag(10086) as? UIProgressView
if progressView == nil {
// print("产生取view ProgressView")
progressView = UIProgressView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: 2))
progressView!.progressTintColor = UIColor(red: 43/255, green: 192/255, blue: 243/255, alpha: 1)
progressView!.progressViewStyle = UIProgressView.Style.bar
progressView!.tag = 10086
self.addSubview(progressView!)
}
return progressView!
}
// print("downloading progress setProgressView: \(progress)")
let progressView = getPview() //自己的progress
// let progress = Float(receivedSize) / Float(totalSize)
// print("下载进度", progress)
if ( progress < 1 ){ //下载进度
progressView.isHidden = false
progressView.setProgress(progress, animated: true)
}
else{
progressView.isHidden = true
// progressView.removeFromSuperview()
}
}
感觉写得不好,希望有大神斧正,而用 removeFromSuperview 有时候会造成崩溃,所以这里用了隐藏
用的时候也是
某imageView.ZImgWithProgressAndCallback( 图像地址url ){
guard let image = $0 else { print("没有图像数据"); return }
// image图片随便专门玩
}
恩,图片读取部分就是这样,
接下来是设置的部分内容,也几乎全改了,不过幅度不大
基本换几个参数方法就可以了
获取图片缓存的大小
//MARK: 图片缓存大小计算
func GetImageCacheSize( _ block:@escaping (String) -> () ){
let cache = ImageCache.default
cache.diskStorage.config.sizeLimit = UInt(200 * 1024 * 1024)
cache.diskStorage.config.expiration = .days(15)
//清除过期缓存
cache.calculateDiskStorageSize { result in
switch result {
case .success(let size):
var dataSize : String{
guard size >= 1024 else { return "\(size) bytes" }
guard size >= 1048576 else { return "\(size / 1024) KB" }
guard size >= 1073741824 else { return "\(size / 1048576) MB" }
return "\(size / 1073741824) GB"
}
block(dataSize)
case .failure(let error):
print("统计图片缓存失败", error)
ZAlertInfo("统计失败", message: "图片缓存信息出现错误", dismissTime: 2)
}
}
使用方法:
GetImageCacheSize(){
print($0)
}
设置图片缓存信息
//MARK: 设置图片缓存大小
func SetImageCache(){
let downloader = ImageDownloader.default
downloader.downloadTimeout = 15 //默认15秒下载超时
let cache = ImageCache.default
// cache.maxMemoryCost = 30 * 1024 * 1024
// 设置最大内存使用量,有可能造成图片下载不完全(待确认)
cache.diskStorage.config.sizeLimit = UInt(200 * 1024 * 1024) //200M 的缓存空间
cache.diskStorage.config.expiration = .days(15) // 15天过期时间 默认是1星期
//需要手动清理过期缓存
cache.cleanExpiredDiskCache()
}
OK,基本到这里了,试用了一天下来
感觉效率和架构比以前版本都更好了,当然初次用起来也更复杂了
而后期特效这块,我基本没用,为了最大的效率,
如果有兴趣的可以专门研究一下,而且预置的 placeholder 图片我也没用,大家可以根据需求加上
此.