forked from shadowfacts/Tusker
62 lines
1.8 KiB
Swift
62 lines
1.8 KiB
Swift
//
|
|
// ImageCache.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfactson 8/21/18.
|
|
// Copyright © 2018 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class AvatarCache {
|
|
|
|
static let shared = AvatarCache()
|
|
|
|
let cache = NSCache<NSString, UIImage>()
|
|
|
|
var requests = [URL: URLSessionDataTask]()
|
|
var requestCallbacks = [URL: [(UIImage?) -> Void]]()
|
|
|
|
|
|
|
|
private init() {
|
|
}
|
|
|
|
func get(_ url: URL, completion: @escaping (UIImage?) -> Void) {
|
|
let key = url.absoluteString as NSString
|
|
if let image = cache.object(forKey: key) {
|
|
completion(image)
|
|
} else if var callbacks = requestCallbacks[url] {
|
|
callbacks.append(completion)
|
|
requestCallbacks[url] = callbacks
|
|
} else {
|
|
requestCallbacks[url] = [completion]
|
|
let task = URLSession.shared.dataTask(with: url) { data, response, error in
|
|
guard error == nil, let data = data, let image = UIImage(data: data) else {
|
|
let callbacks = self.requestCallbacks.removeValue(forKey: url)
|
|
callbacks?.forEach({ callback in
|
|
// todo: default avatar for failed requests
|
|
callback(nil)
|
|
})
|
|
return
|
|
}
|
|
|
|
let callbacks = self.requestCallbacks.removeValue(forKey: url)
|
|
callbacks?.forEach({ callback in
|
|
callback(image)
|
|
})
|
|
self.cache.setObject(image, forKey: key)
|
|
}
|
|
task.resume()
|
|
requests[url] = task
|
|
}
|
|
}
|
|
|
|
func cancel(_ url: URL) {
|
|
requests[url]?.cancel()
|
|
requests.removeValue(forKey: url)
|
|
requestCallbacks.removeValue(forKey: url)
|
|
}
|
|
|
|
}
|