bind images and fix ranking row (#36)
Co-authored-by: ludelanier <lucas.delanier@etu.uca.fr> Reviewed-on: #36pull/38/head
parent
5d1ea8492a
commit
ef1f130ec5
@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// asyncCachedImage.swift
|
||||||
|
// AllIn
|
||||||
|
//
|
||||||
|
// Created by Lucas Delanier on 06/06/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
struct AsyncCachedImage<ImageView: View, PlaceholderView: View>: View {
|
||||||
|
// Input dependencies
|
||||||
|
var url: URL?
|
||||||
|
@ViewBuilder var content: (Image) -> ImageView
|
||||||
|
@ViewBuilder var placeholder: () -> PlaceholderView
|
||||||
|
|
||||||
|
// Downloaded image
|
||||||
|
@State var image: UIImage? = nil
|
||||||
|
|
||||||
|
init(
|
||||||
|
url: URL?,
|
||||||
|
@ViewBuilder content: @escaping (Image) -> ImageView,
|
||||||
|
@ViewBuilder placeholder: @escaping () -> PlaceholderView
|
||||||
|
) {
|
||||||
|
self.url = url
|
||||||
|
self.content = content
|
||||||
|
self.placeholder = placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
if let uiImage = image {
|
||||||
|
content(Image(uiImage: uiImage))
|
||||||
|
} else {
|
||||||
|
placeholder()
|
||||||
|
.onAppear {
|
||||||
|
Task {
|
||||||
|
image = await downloadPhoto()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Downloads if the image is not cached already
|
||||||
|
// Otherwise returns from the cache
|
||||||
|
private func downloadPhoto() async -> UIImage? {
|
||||||
|
do {
|
||||||
|
guard let url else { return nil }
|
||||||
|
|
||||||
|
// Check if the image is cached already
|
||||||
|
if let cachedResponse = URLCache.shared.cachedResponse(for: .init(url: url)) {
|
||||||
|
return UIImage(data: cachedResponse.data)
|
||||||
|
} else {
|
||||||
|
let (data, response) = try await URLSession.shared.data(from: url)
|
||||||
|
|
||||||
|
// Save returned image data into the cache
|
||||||
|
URLCache.shared.storeCachedResponse(.init(response: response, data: data), for: .init(url: url))
|
||||||
|
|
||||||
|
guard let image = UIImage(data: data) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error downloading: \(error)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue