参考:https://www.jianshu.com/p/55bbfbdf78de
=============方法一:使用sdwebImage
下载地址:https://github.com/rs/SDWebImage
在桥接文件中导入
#import <SDWebImage/UIImageView+WebCache.h>
let imagev:UIImageView=UIImageView.init(frame:CGRect(x:0,y:0,width:100,height:100))
view .addSubview(imagev)
imagev.sd_setImage(with: NSURL.init(string: "http://test.ahwofu.com/public/upload/ad/2018/01-13/abc1cc5d2e661e4a")! as URL, placeholderImage: UIImage.init(named: "bannerhomeOne"), options: [], progress: nil, completed:nil)
==============方法二:Kingfisher
下载地址:https://github.com/onevcat/Kingfisher
Kingfisher是一个开源处理图片加载、缓存的开源库;
Kingfisher 有如下特性:
- 异步:使用Kingfisher操作的所有事件都是异步的,包括下载、检索、缓存,你无须担心UI线程阻塞问题
- 多级缓存:下载的图片可以缓存至内存和Disk,如果你重新下载相同的图片,多级缓存将会显著的加快你得到结果
- Mordern Framework:Kingfisher使用的是NSURLSession 以及最新的GCD,让你更方便的使用
- 可取消的任务:你可以取消你不想下载的任何任务
- 独立的组件:你可以单独的使用Downloader,也可以单独的使用Cache来创建你独立的多级缓存
- UI显示提升:在后台线程解压缩你的图片
- Extensions:提供了UIImageView与UIButton的扩展,方便你可以通过URL来显示你的图片
图片缓存ImageCache 使用:
ImageChache 给你提供了多级缓存,可以使用内存、磁盘存储,还提供了存储、检索、清除图片、移除等操作,如果你需要监听到磁盘的变化可以通过KingfisherDidCleanDiskCacheNotification
添加通知。
//缓存的一些设置
func kfishsetcache(imageview:UIImageView,urlstr:String){
let cacheKey:String="mycache"
// ImageCache,默认是
let cache = ImageCache.default
//内存默认的缓存限制,最多存储内存大小的四分之一,图片个数无限制
// 内存缓存大小,限制在300M
cache.memoryStorage.config.totalCostLimit = 300 * 1024 * 1024
//缓存图片的个数最多150个
cache.memoryStorage.config.countLimit = 150
// 磁盘存储大小的限制1000M
cache.diskStorage.config.sizeLimit = 1000 * 1024 * 1024
//内存中缓存默认的过期时间是5分钟,磁盘是一周过期
//设置内现存过期时间是600秒
cache.memoryStorage.config.expiration = .seconds(600)
/*设置磁盘过期是永远不过期
.never 永不过期
.expired 立马过期,等于不存储
days()
date()
seconds()
*/
cache.diskStorage.config.expiration = .never
//专门为某一张图片设置过期时间
let url=URL.init(string: urlstr)
imageview.kf.setImage(with: url, options: [.memoryCacheExpiration(.never)])
//每隔30秒清除一次缓存,这个貌似现在不好使
// cache.memoryStorage.config.cleanInterval = 30
let processor = RoundCornerImageProcessor(cornerRadius: 20)
imageview.kf.setImage(with: url, options: [.processor(processor)])
//判断是否有叫cacheKey名字的缓存
cache.isCached(forKey: cacheKey, processorIdentifier: processor.identifier)
//获取缓存的类型,是内存缓存或者磁盘缓存,无缓存
let cacheType = cache.imageCachedType(forKey: cacheKey)
//默认情况下会自动缓存
//自己操作缓存
let data: Data = urlstr.data(using: String.Encoding.utf8)!
let image: UIImage = UIImage.init(named: urlstr)!
cache.store(image, forKey: cacheKey)
cache.store(image, original: data, forKey: cacheKey)
//带有identify的cache
let mycache = ImageCache(name: "my-own-cache")
imageview.kf.setImage(with: url, options: [.targetCache(mycache)])
//获取缓存数据
cache.retrieveImage(forKey: "cacheKey") { result in
switch result {
case .success(let value):
print(value.cacheType)
// If the `cacheType is `.none`, `image` will be `nil`.
print(value.image)
case .failure(let error):
print(error)
}
}
//移除缓存
ImageCache.default.removeImage(forKey: cacheKey)
let processor1 = RoundCornerImageProcessor(cornerRadius: 20)
cache.removeImage(
forKey: cacheKey,
processorIdentifier: processor1.identifier,
fromMemory: false,
fromDisk: true)
{
print("Removed!")
}
// Remove all.
cache.clearMemoryCache()
cache.clearDiskCache { print("Done") }
// Remove only expired.
cache.cleanExpiredMemoryCache()
cache.cleanExpiredDiskCache { print("Done") }
//计算磁盘缓存的大小
ImageCache.default.calculateDiskStorageSize { result in
switch result {
case .success(let size):
print("Disk cache size: \(Double(size) / 1024 / 1024) MB")
case .failure(let error):
print(error)
}
}
// 监听数据移除
NotificationCenter.default.addObserver(self, selector:#selector(cleanDiskCache), name: NSNotification.Name.init("KingfisherDidCleanDiskCacheNotification"), object:nil)
}
==========下载图片带进度
使用ImageDownloader下载图片,它为我们提供了一些头的设置(比如说你有些图片是需要认证用户才能下载的);安全设置:我们在下载图片时哪些Host是可信任的;下载超时设置;下载回调等
/*
带进度,可取消的下载
使用:
let imagev:UIImageView=UIImageView.init(frame:CGRect(x:0,y:50,width:100,height:100))
view.addSubview(imagev)
LYBKingfisherDownloadExample.init().kfishdownloadprogress(imageview:
imagev, urlstr: "https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-
process=image/resize,m_lfit,w_268,limit_1/format,f_jpg")
*/
func kfishdownloadprogress(imageview:UIImageView,urlstr:String){
//设置下载器
let downloader = ImageDownloader.default
// 设置可信任的Host
// let hosts: Set<String> = ["http://xxxxx.com","http://#####.com"]
// downloader.trustedHosts = hosts
// 设置sessionConfiguration
downloader.sessionConfiguration = URLSessionConfiguration.default
// 设置代理,详情参考 ImageDownloaderDelegate
downloader.delegate = self
// 下载超时设置
downloader.downloadTimeout = 20
// 下载图片
let url=URL.init(string:urlstr)
let retriveTask = downloader.downloadImage(with: url!, options:nil) { (nowsize, total) in
print("nowsize\(nowsize)---\(total)")
} completionHandler: { (result) in
print("result-\(result)")
switch result {
case .success:
imageview.image=try! result.get().image
case .failure:
break
}
}
// // 取消下载
// retriveTask?.cancel()
}
=====下载不带缓存===
//下载图片不带缓存
func dowloadwithoutcache(imageview:UIImageView,urlstr:String){
let url=URL.init(string:urlstr)
let downloader = ImageDownloader.default
downloader.downloadImage(with: url!) { result in
switch result {
case .success(let value):
print(value.image)
case .failure(let error):
print(error)
}
}
}
=====================直接imageview扩展下载设置图片
在File.swift文件中全局引入@_exported import Kingfisher
引入import Kingfisher
extension UIImageView{
/*普通下载
let imagev:UIImageView=UIImageView.init(frame:CGRect(x:0,y:50,width:100,height:100))
view.addSubview(imagev)
UIImageView.kfishdownload(imageview: imagev,urlstr: "https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg")
*/
class func kfishdownload(imageview:UIImageView,urlstr:String,placeholdimagename:String){
imageview.kf.setImage(with:ImageResource(downloadURL:URL.init(string:urlstr)!))
//或者
let url=URL.init(string:urlstr)
imageview.kf.setImage(with: url, placeholder: UIImage.init(named: placeholdimagename))
}
}
============主控制器KingfisherManager配置
KingfisherManager是连接ImageDownloader与ImageCache的,所以你可以通过manager得到 downloader与cache,并且还能改设置加载选项,当然你也可以设置其他的ImageDownloader与ImageCache到你的Manager。
/*
配置
*/
class func kfishManager(imageview:UIImageView,urlstr:String){
let kfManager = KingfisherManager.shared
let newCache:ImageCache?
// 通过manager 获取cache
newCache = kfManager.cache
// 通过manager 获取downloader
let newDownloader:ImageDownloader?
newDownloader = kfManager.downloader
// 设置options, 你可以设置你的newCache/newDownloader以及其他配置
kfManager.defaultOptions = [.targetCache(newCache!), .downloader(newDownloader!), .forceRefresh, .backgroundDecode, .onlyFromCache, .downloadPriority(1.0)]
let url=URL.init(string:urlstr)
// 检索(retrieve取回)
let resource = ImageResource(downloadURL:url!, cacheKey:"text")
let retriveImageTask = kfManager.retrieveImage(with: resource, options:[]) { (nowsize, total) in
//
} downloadTaskUpdated: { (downloadtask) in
//
} completionHandler: { (result) in
print("\(result)")
switch result {
case .success:
imageview.image=try! result.get().image
case .failure:
break
}
}
// 取消下载
// retriveImageTask!.cancel()
}
=====链式调用下载图片====
extension UIImageView{
//链式调用
class func kfishdownloadchain(imageview:UIImageView,urlstr:String){
let url = URL(string: urlstr)
let placeholderImage:UIImage=UIImage.init(named: "center")!
//Processor种类很多
let processor = RoundCornerImageProcessor(cornerRadius: 20)
let lowResolutionURL=URL.init(string: urlstr)
KF.url(url!)
.placeholder(placeholderImage)
.setProcessor(processor)
.loadDiskFileSynchronously()
.cacheMemoryOnly()
.fade(duration: 0.25)
.lowDataModeSource(.network(lowResolutionURL!))
.onProgress { receivedSize, totalSize in }
.onSuccess { result in }
.onFailure { error in }
.set(to: imageview)
}
}
=====一些设置======
/*一些设置
*/
class func kfdownloadwithsomesetting(imageview:UIImageView,urlstr:String){
let url = URL(string: urlstr)
//处理器
let processor = DownsamplingImageProcessor(size: imageview.bounds.size)
|> RoundCornerImageProcessor(cornerRadius: 20)
imageview.kf.indicatorType = .activity
imageview.kf.setImage(
with: url,
placeholder: UIImage(named: "center"),
options: [
.processor(processor),
.scaleFactor(UIScreen.main.scale),
.transition(.fade(1)),
.cacheOriginalImage
])
{
result in
switch result {
case .success:
// imageview.image=value.image
imageview.image=try! result.get().image
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
}
=====下载之前改变request===
//下载之前改变request
class func kfishdownloadmodifyrewuest(imageview:UIImageView,urlstr:String){
let downloader = ImageDownloader.default
let url = URL(string: urlstr)
let modifier = AnyModifier { request in
var r = request
r.setValue("abc", forHTTPHeaderField: "Access-Token")
return r
}
downloader.downloadImage(with: url!, options: [.requestModifier(modifier)]) {
result in
print("\(result)")
}
imageview.kf.setImage(with: url, options: [.requestModifier(modifier)])
}
====下载带超时====
//下载带超时
class func downloadtimeout(imageview:UIImageView,urlstr:String){
let downloader = ImageDownloader.default
downloader.downloadTimeout=60//超时60秒
let url = URL(string: urlstr)
let modifier = AnyModifier { request in
var r = request
r.timeoutInterval = 60
return r
}
downloader.downloadImage(with: url!, options: [.requestModifier(modifier)])
}
====处理器processor的设置===
//processor处理下载的图片
func kfishdownloadwithprocessor(imageview:UIImageView,urlstr:String){
let url = URL(string: urlstr)
// Round corner
let processor = RoundCornerImageProcessor(cornerRadius: 20)
// // Downsampling
// let processor2 = DownsamplingImageProcessor(size: CGSize(width: 100, height: 100))
//
// // Cropping
// let processor3 = CroppingImageProcessor(size: CGSize(width: 100, height: 100), anchor: CGPoint(x: 0.5, y: 0.5))
//
// // Blur
// let processor4 = BlurImageProcessor(blurRadius: 5.0)
//
// // Overlay with a color & fraction
// let processor5 = OverlayImageProcessor(overlay: .red, fraction: 0.7)
//
// // Tint with a color
// let processor6 = TintImageProcessor(tint: .blue)
//
// // Adjust color
// let processor7 = ColorControlsProcessor(brightness: 1.0, contrast: 0.7, saturation: 1.1, inputEV: 0.7)
//
// // Black & White
// let processor8 = BlackWhiteProcessor()
//
// // Blend (iOS)
// let processor9 = BlendImageProcessor(blendMode: .darken, alpha: 1.0, backgroundColor: .lightGray)
// //复合处理器
// let processor10 = BlurImageProcessor(blurRadius: 4) |> RoundCornerImageProcessor(cornerRadius: 20)
// Use the process in view extension methods.
imageview.kf.setImage(with: url, options: [.processor(processor)])
}
====本地下载====
//从本地下载
class func kfishsdownloadfromfile(imageview:UIImageView,path:String){
let url = URL(fileURLWithPath: path)
let provider = LocalFileImageDataProvider(fileURL: url)
let processor = RoundCornerImageProcessor(cornerRadius: 20)
imageview.kf.setImage(with: provider, options: [.processor(processor)])
}
//从本地下载
class func kfishsdownloadfrombase64String(imageview:UIImageView,base64Sting:String){
let provider = Base64ImageDataProvider(base64String: base64Sting, cacheKey: "some-cache-key")
imageview.kf.setImage(with: provider)
}
//从本地下载
class func kfishsdownloadfromAVAsset(imageview:UIImageView,urlstr:String){
let provider = AVAssetImageDataProvider(
assetURL: URL(string: "https://example.com/your_video.mp4")!,
seconds: 15.0
)
imageview.kf.setImage(with: provider)
}
================扩展
Kingfisher 提供了UIButton与UIImageView的扩展,使你可以通过直接设置图片URL来显示,两者用法差不多,以UIImageView为例:
// 设置网络图片
imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!))
imageView.kf.setImage(with: ImageResource(downloadURL: imageURL!), placeholder:UIImage(named: "test"), options:nil, progressBlock: nil, completionHandler: nil)
// UIImageView 也可以设置取消加载 (两种方式)
imageView.kf.cancelDownloadTask()
let retriveImageTask = imageView.kf.setImage(with:ImageResource(downloadURL: imageURL!))
retriveImageTask.cancel()