最近 swift 又升級(jí)穴翩,我原本的 app 支持版本是到 iOS 9例诀,
而 iOS 10 是 16年發(fā)布的片效,3年時(shí)間高中都快讀完了橙数,
發(fā)現(xiàn)不少 cocoapods 的庫(kù)最新版本已經(jīng)從 iOS 10 起跳支持
比如我們這篇的主角 Kingfisher 七巧板
貓大,onevcat大神所寫虐杯,感謝大神的無(wú)私分享玛歌,
從swift面世至今,Kingfisher 感覺就是 oc時(shí)代的 SDWebImage
圖片下載的江湖地位無(wú)可替代厦幅,4.0 之前 api 基本相同并兼容沾鳄,
就算是 swift 大版本更新,老項(xiàng)目改改參數(shù)就能繼續(xù)用
不過這次更新5以后确憨,簡(jiǎn)直就是大換血译荞,偏偏在網(wǎng)上找不到中文的文檔
經(jīng)過仔細(xì)看完wiki后,這里做個(gè)筆錄休弃,方便自己也方便后來(lái)人
隨意轉(zhuǎn)載吞歼,記得注明出處便可
如果是最基本的使用,那和以前一樣塔猾,直接開箱可用
這里我直接把它做成了 UIImageView的擴(kuò)展
extension UIImageView {
func ZImg(_ link : String ) {
self.kf.indicatorType = .activity
guard let nurl = URL(string: url) else {print("無(wú)圖片", url); return }
let option : KingfisherOptionsInfo = [
.backgroundDecode, //后臺(tái)解碼 gif
.onlyLoadFirstFrame, //gif 只讀第一幀
// .fromMemoryCacheOrRefresh //如果設(shè)置篙骡,Kingfisher會(huì)嘗試從內(nèi)存緩存中首先檢索圖像。 如果圖像不在內(nèi)存緩存中丈甸,則會(huì)忽略磁盤緩存糯俗,但是會(huì)再次從網(wǎng)絡(luò)下載圖像
]
self.kf.setImage(with: nurl, options: option)
}
}
用的時(shí)候直接 專門的imageView.ZImg( 圖片地址 ),就可以正常使用
但如果是要獲得下載完成回調(diào)的情況睦擂,幾乎以前的寫法就完全改完了
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)")
}
}
}
這樣就是帶有回調(diào)了得湘,但會(huì)常出現(xiàn)下載文件差別的錯(cuò)誤,不過基本可以不理顿仇,可以用這個(gè)方法判斷圖片是否存在
let is404 = error.isInvalidResponseStatusCode(404) //true就是404錯(cuò)誤淘正,圖片不存在
最終寫出一個(gè)帶下載進(jìn)度條的版本
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
//直接當(dāng)前頁(yè)面處理下載進(jìn)度條
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)") //其他錯(cuò)誤不管
let is404 = error.isInvalidResponseStatusCode(404)
if(is404){
ZAlertInfo("圖片不存在", dismissTime: 2) //自己的警告方法
}
}
}
} //ZImgWithProgressAndCallback
而下載進(jìn)度條的方法是這樣
func setProgressView(_ progress: Float){
func getPview() -> UIProgressView{
// print("讀取view")
var progressView: UIProgressView? = self.viewWithTag(10086) as? UIProgressView
if progressView == nil {
// print("產(chǎn)生取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("下載進(jìn)度", progress)
if ( progress < 1 ){ //下載進(jìn)度
progressView.isHidden = false
progressView.setProgress(progress, animated: true)
}
else{
progressView.isHidden = true
// progressView.removeFromSuperview()
}
}
感覺寫得不好摆马,希望有大神斧正,而用 removeFromSuperview 有時(shí)候會(huì)造成崩潰鸿吆,所以這里用了隱藏
用的時(shí)候也是
某imageView.ZImgWithProgressAndCallback( 圖像地址url ){
guard let image = $0 else { print("沒有圖像數(shù)據(jù)"); return }
// image圖片隨便專門玩
}
恩囤采,圖片讀取部分就是這樣,
接下來(lái)是設(shè)置的部分內(nèi)容惩淳,也幾乎全改了蕉毯,不過幅度不大
基本換幾個(gè)參數(shù)方法就可以了
獲取圖片緩存的大小
//MARK: 圖片緩存大小計(jì)算
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("統(tǒng)計(jì)圖片緩存失敗", error)
ZAlertInfo("統(tǒng)計(jì)失敗", message: "圖片緩存信息出現(xiàn)錯(cuò)誤", dismissTime: 2)
}
}
使用方法:
GetImageCacheSize(){
print($0)
}
設(shè)置圖片緩存信息
//MARK: 設(shè)置圖片緩存大小
func SetImageCache(){
let downloader = ImageDownloader.default
downloader.downloadTimeout = 15 //默認(rèn)15秒下載超時(shí)
let cache = ImageCache.default
// cache.maxMemoryCost = 30 * 1024 * 1024
// 設(shè)置最大內(nèi)存使用量,有可能造成圖片下載不完全(待確認(rèn))
cache.diskStorage.config.sizeLimit = UInt(200 * 1024 * 1024) //200M 的緩存空間
cache.diskStorage.config.expiration = .days(15) // 15天過期時(shí)間 默認(rèn)是1星期
//需要手動(dòng)清理過期緩存
cache.cleanExpiredDiskCache()
}
OK黎泣,基本到這里了恕刘,試用了一天下來(lái)
感覺效率和架構(gòu)比以前版本都更好了缤谎,當(dāng)然初次用起來(lái)也更復(fù)雜了
而后期特效這塊抒倚,我基本沒用,為了最大的效率坷澡,
如果有興趣的可以專門研究一下托呕,而且預(yù)置的 placeholder 圖片我也沒用,大家可以根據(jù)需求加上
此.