Skip to content

Instantly share code, notes, and snippets.

@iamraafay
Last active January 16, 2023 10:09
Show Gist options
  • Save iamraafay/5b588676fc1e309b5bdc3189d805fb59 to your computer and use it in GitHub Desktop.
Save iamraafay/5b588676fc1e309b5bdc3189d805fb59 to your computer and use it in GitHub Desktop.
UIImageView Caching
import UIKit
/*With GCD*/
extension UIImageView {
func loadImage(from url: URL?) {
guard let url = url else { return }
let cache = URLCache.shared
let request = URLRequest(url: url)
DispatchQueue.global(qos: .background).async {
if let data = cache.cachedResponse(for: request)?.data, let image = UIImage(data: data) {
DispatchQueue.main.async {
self.transition(to: image)
}
} else {
URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let response = response, let data = data, let image = UIImage(data: data) {
let cachedData = CachedURLResponse(response: response, data: data)
cache.storeCachedResponse(cachedData, for: request)
DispatchQueue.main.async {
self.transition(to: image)
}
}
}).resume()
}
}
}
private func transition(to image: UIImage) {
UIView.transition(with: self, duration: 0.3,
options: [.transitionCrossDissolve],
animations: { self.image = image },
completion: nil)
}
}
/* With Task API */
extension UIImageView {
func loadImage(from url: URL?, withImagePlaceholder placeholder: UIImage? = nil, withAnimation animation: Bool = true) {
image = placeholder
guard let url = url else { return }
let cache = URLCache.shared
let request = URLRequest(url: url)
Task {
if let data = cache.cachedResponse(for: request)?.data, let image = UIImage(data: data) {
Task { @MainActor in self.transition(to: image, withAnimation: animation) }
} else {
let (data, response) = try await URLSession.shared.data(for: request)
let cachedData = CachedURLResponse(response: response, data: data)
cache.storeCachedResponse(cachedData, for: request)
guard let image = UIImage(data: data) else { return }
Task { @MainActor in self.transition(to: image, withAnimation: animation) }
}
}
}
private func transition(to image: UIImage, withAnimation animation: Bool) {
guard animation else {
self.image = image
return
}
UIView.transition(with: self, duration: 0.3,
options: [.transitionCrossDissolve],
animations: { self.image = image },
completion: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment