Last active
October 27, 2020 12:44
-
-
Save leoniralves/4ba24c8326f76a69bafce4a6e0f21f92 to your computer and use it in GitHub Desktop.
Swift extension for asynchronous image loading
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
protocol Cacheable { | |
associatedtype Key | |
associatedtype Object | |
func set(key: Key, object: Object) | |
func get(key: Key) -> Object? | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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