Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SwiftUI ImageLoader with caching
let url = URL(string: "https://mist.eivindml.now.sh/static/Artboard.png")!
struct GameDetail: View {
@State var nowDate = Date()
private var refDate: Date {
let formatter = DateFormatter()
formatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
let rDate = formatter.date(from: "20019-10-11 12:12:12")
return rDate!
}
private var timer: Timer {
return Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
self.nowDate = Date()
}
}
var body: some View {
VStack {
URLImage(url: url)
Text("\(nowDate.distance(to: refDate).description) Until game release")
}
.onAppear {
_ = self.timer
}
}
}
import SwiftUI
let imageCache = NSCache<AnyObject, AnyObject>()
final class ImageLoader: ObservableObject {
private var task: URLSessionDataTask?
@Published var data: Data?
init(_ url: URL) {
task = URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data, let imageToCache = UIImage(data: data) {
imageCache.setObject(imageToCache, forKey: url as AnyObject)
}
DispatchQueue.main.async { self.data = data }
}
task?.resume()
}
deinit {
task?.cancel()
}
}
let imagePlaceholder = UIImage(named: "gameImage")!
struct URLImage: View {
@ObservedObject private var imageLoader: ImageLoader
private let url: URL
init(url: URL) {
self.url = url
self.imageLoader = ImageLoader(url)
}
var image: UIImage? {
if let imageFromCache = imageCache.object(forKey: url as AnyObject) as? UIImage {
return imageFromCache
}
return imageLoader.data.flatMap(UIImage.init)
}
var body: Image {
Image(uiImage: image ?? imagePlaceholder)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment