Skip to content

Instantly share code, notes, and snippets.

@liamnichols
Created August 8, 2017 10:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liamnichols/cd037b7b00ff1a7e3f75288b97f69b1a to your computer and use it in GitHub Desktop.
Save liamnichols/cd037b7b00ff1a7e3f75288b97f69b1a to your computer and use it in GitHub Desktop.
Why use a library when its this easy?
import UIKit
extension URLSessionTask: WebImageOperation { }
protocol WebImageOperation {
func cancel()
}
class WebImageManager {
struct Error: Swift.Error {
enum Code {
case imageDecoding
case networking
}
let code: Code
}
static let shared = WebImageManager()
private let session: URLSession
private let cache: URLCache
init(memoryCapacity: Int = 10 * 1024 * 1024, diskCapacity: Int = 256 * 1024 * 1024) {
let cache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: nil)
let config = URLSessionConfiguration.default
config.requestCachePolicy = .returnCacheDataElseLoad
config.timeoutIntervalForRequest = 30.0
config.urlCache = cache
if UserDefaults.standard.resetImageCache {
cache.removeAllCachedResponses()
}
self.cache = cache
self.session = URLSession(configuration: config)
}
func cachedImage(from url: URL) -> UIImage? {
if let response = cache.cachedResponse(for: request(for: url)) {
return UIImage(data: response.data)
} else {
return nil
}
}
@discardableResult func loadImage(from url: URL, callback: @escaping (UIImage?, Error?) -> Swift.Void) -> WebImageOperation {
NetworkActivityIndicatorManager.shared.incrementActivityCount()
let task = session.dataTask(with: request(for: url)) { data, response, error in
NetworkActivityIndicatorManager.shared.decrementActivityCount()
// Load the image
let error: Error?
let image: UIImage?
if let data = data {
if let decoded = UIImage(data: data) {
error = nil
image = decoded
} else {
error = Error(code: .imageDecoding)
image = nil
}
} else {
error = Error(code: .networking)
image = nil
}
// Callback iwth the result
DispatchQueue.main.async {
callback(image, error)
}
}
task.resume()
return task
}
private func request(for url: URL) -> URLRequest {
return URLRequest(url: url,
cachePolicy: session.configuration.requestCachePolicy,
timeoutInterval: session.configuration.timeoutIntervalForRequest)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment