前言

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