Skip to content

Instantly share code, notes, and snippets.

@leoniralves
Last active October 27, 2020 12:44
Show Gist options
  • Save leoniralves/4ba24c8326f76a69bafce4a6e0f21f92 to your computer and use it in GitHub Desktop.
Save leoniralves/4ba24c8326f76a69bafce4a6e0f21f92 to your computer and use it in GitHub Desktop.
Swift extension for asynchronous image loading
import Foundation
protocol Cacheable {
associatedtype Key
associatedtype Object
func set(key: Key, object: Object)
func get(key: Key) -> Object?
}
import UIKit
extension UIImageView {
private struct AssociatedKeys {
static var sessionDataTask = "sessionDataTask"
}
private var task: URLSessionDataTask? {
get {
return objc_getAssociatedObject(self,
&AssociatedKeys.sessionDataTask) as? URLSessionDataTask
}
set {
if let newValue = newValue {
objc_setAssociatedObject(self,
&AssociatedKeys.sessionDataTask,
newValue,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
/// Download de imagens
/// - Parameters:
/// - url: Url da imagem
/// - placeholder: View de apresentação enquanto a imagem não foi obtida
/// - cache: Objeto para manter a image de forma local e temporária
func load<T: Cacheable>(url: URL,
placeholder: UIView?,
cache: T?) where T.Key == String, T.Object == UIImage {
if let imageCache = cache?.get(key: url.absoluteString) {
self.image = imageCache
} else {
task?.cancel()
task = nil
placeholder?.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(placeholder)
placeholder?.allAnchor(equalTo: self)
task = URLSession.shared.dataTask(with: url) { (data, _, _) in
DispatchQueue.main.async {
placeholder?.removeFromSuperview()
guard self.task != nil,
let data = data else {
return
}
guard let image = UIImage(data: data) else {
return
}
self.image = image
cache?.set(key: url.absoluteString,
object: image)
}
}
task?.resume()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment