给AsyncDisplayKit(Texture)替换网络图片下载缓存框架
前言 为了方便管理图片缓存,统一缓存文件夹和缓存方法,将AsyncDisplayKit自带的PINRemoteImage插件, 替换为项目在用的Kingfisher、SDWebImage。 1import Kingfisher 2 3extension ASNetworkImageNode { 4 static func imageNode() -> ASNetworkImageNode { 5 return ASNetworkImageNode(cache: ASImageManager.shared, downloader: ASImageManager.shared) 6 } 7} 8 9class ASImageManager: NSObject, ASImageDownloaderProtocol, ASImageCacheProtocol { 10 11 static let shared = ASImageManager() 12 private override init() {} 13 14 func downloadImage(with url: URL, callbackQueue: DispatchQueue, downloadProgress: ASImageDownloaderProgress?, completion: @escaping ASImageDownloaderCompletion) -> Any? { 15 16 ImageDownloader.default.downloadTimeout = 30.0 17 var operation: DownloadTask? 18 operation = ImageDownloader.default.downloadImage(with: url, options: nil, progressBlock: { (received, expected) in 19 if downloadProgress != nil { 20 callbackQueue.async(execute: { 21 let progress = expected == 0 ? 0 : received / expected 22 downloadProgress?(CGFloat(progress)) 23 }) 24 } 25 }) { (result) in 26 switch result { 27 case .success(let value): 28 callbackQueue.async(execute: { completion(value.image, nil, nil, nil) }) 29 ImageCache.default.store(value.image, original: value.originalData, forKey: url.cacheKey, toDisk: true) 30 case .failure(let error): 31 callbackQueue.async(execute: { completion(nil, error, operation, nil) }) 32 dPrint("Job failed: \(error.localizedDescription)") 33 } 34 } 35 36 return operation 37 } 38 39 func cancelImageDownload(forIdentifier downloadIdentifier: Any) { 40 if let task = downloadIdentifier as? DownloadTask { 41 task.cancel() 42 } 43 } 44 45 func cachedImage(with url: URL, callbackQueue: DispatchQueue, completion: @escaping ASImageCacherCompletion) { 46 ImageCache.default.retrieveImage(forKey: url.cacheKey) { (result) in 47 switch result { 48 case .success(let value): 49 callbackQueue.async { completion(value.image) } 50 case .failure(let error): 51 dPrint("Job failed: \(error.localizedDescription)") 52 } 53 } 54 } 55} 1import SDWebImage 2 3extension ASNetworkImageNode { 4 static func imageNode() -> ASNetworkImageNode { 5 return ASNetworkImageNode(cache: ASNetImageManage.shared, downloader: ASNetImageManage.shared) 6 } 7} 8 9class ASNetImageManage: NSObject, ASImageDownloaderProtocol, ASImageCacheProtocol { 10 11 static let shared = ASNetImageManage() 12 13 func downloadImage(with URL: URL, callbackQueue: DispatchQueue, downloadProgress: ASImageDownloaderProgress?, completion: @escaping ASImageDownloaderCompletion) -> Any? { 14 15 weak var weakOperation: SDWebImageOperation? 16 let operation = SDWebImageManager.shared.loadImage(with: URL, options: .retryFailed, progress: { (received, expected, url) in 17 if downloadProgress != nil { 18 callbackQueue.async(execute: { 19 let progress = expected == 0 ? 0 : received / expected 20 downloadProgress?(CGFloat(progress)) 21 }) 22 } 23 }) { (cachedImage, data, error, type, unknow, url) in 24 if let image = cachedImage { 25 callbackQueue.async(execute: { completion(image, nil, nil, nil) }) 26 return 27 } 28 callbackQueue.async(execute: { completion(nil, error, nil, nil) }) 29 } 30 weakOperation = operation 31 return weakOperation 32 } 33 34 func cancelImageDownload(forIdentifier downloadIdentifier: Any) { 35 if let downloadIdentifier = downloadIdentifier as? SDWebImageOperation { 36 downloadIdentifier.cancel() 37 } 38 } 39 40 func cachedImage(with URL: URL, callbackQueue: DispatchQueue, completion: @escaping ASImageCacherCompletion) { 41 42 if let key = SDWebImageManager.shared.cacheKey(for: URL) { 43 SDWebImageManager.shared.imageCache.queryImage(forKey: key, options: .allowInvalidSSLCertificates, context: nil) { (cachedImage, data, type) in 44 if let image = cachedImage { 45 callbackQueue.async(execute: { completion(image) }) 46 return 47 } 48 callbackQueue.async(execute: { completion(nil) }) 49 } 50 }else { 51 callbackQueue.async { 52 completion(nil) 53 } 54 } 55 56 } 57}