前言
为了方便管理图片缓存,统一缓存文件夹和缓存方法,将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}