diff --git a/Evergreen/Images/ImageDownloader.swift b/Evergreen/Images/ImageDownloader.swift index 4af6f4a2d..3f079178e 100644 --- a/Evergreen/Images/ImageDownloader.swift +++ b/Evergreen/Images/ImageDownloader.swift @@ -21,7 +21,9 @@ final class ImageDownloader { private var diskCache: BinaryDiskCache private let queue: DispatchQueue private var imageCache = [String: NSImage]() // url: image - + private var urlsInProgress = Set() + private var badURLs = Set() // That return a 404 or whatever. Just skip them in the future. + struct UserInfoKey { static let imageURL = "imageURL" } @@ -33,6 +35,7 @@ final class ImageDownloader { self.queue = DispatchQueue(label: "ImageDownloader serial queue - \(folder)") } + @discardableResult func image(for url: String) -> NSImage? { if let image = imageCache[url] { @@ -54,10 +57,16 @@ private extension ImageDownloader { func findImage(_ url: String) { + guard !urlsInProgress.contains(url) && !badURLs.contains(url) else { + return + } + urlsInProgress.insert(url) + readFromDisk(url) { (image) in if let image = image { self.cacheImage(url, image) + self.urlsInProgress.remove(url) return } @@ -66,6 +75,7 @@ private extension ImageDownloader { if let image = image { self.cacheImage(url, image) } + self.urlsInProgress.remove(url) } } } @@ -87,19 +97,22 @@ private extension ImageDownloader { func downloadImage(_ url: String, _ callback: @escaping (NSImage?) -> Void) { - guard let url = URL(string: url) else { + guard let imageURL = URL(string: url) else { callback(nil) return } - downloadUsingCache(url) { (data, response, error) in + downloadUsingCache(imageURL) { (data, response, error) in if let data = data, !data.isEmpty, let response = response, response.statusIsOK, error == nil { - self.saveToDisk(url.absoluteString, data) + self.saveToDisk(url, data) NSImage.rs_image(with: data, imageResultBlock: callback) return } + if let response = response as? HTTPURLResponse, response.statusCode >= HTTPResponseCode.badRequest && response.statusCode <= HTTPResponseCode.notAcceptable { + self.badURLs.insert(url) + } if let error = error { appDelegate.logMessage("Error downloading image at \(url): \(error)", type: .warning) }