Keep track of bad URLs and URLs in progress in ImageDownloader.

This commit is contained in:
Brent Simmons 2017-11-25 20:24:38 -08:00
parent 18f6b177e9
commit b9c562b77a
1 changed files with 17 additions and 4 deletions

View File

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