Initial Commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// CachedAsyncImage.swift
|
||||
// Mobile Music Assistant
|
||||
//
|
||||
// Created by Sven Hanold on 26.03.26.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// AsyncImage with URLCache support for album covers
|
||||
struct CachedAsyncImage<Content: View, Placeholder: View>: View {
|
||||
let url: URL?
|
||||
let content: (Image) -> Content
|
||||
let placeholder: () -> Placeholder
|
||||
|
||||
@State private var image: UIImage?
|
||||
@State private var isLoading = false
|
||||
|
||||
init(
|
||||
url: URL?,
|
||||
@ViewBuilder content: @escaping (Image) -> Content,
|
||||
@ViewBuilder placeholder: @escaping () -> Placeholder
|
||||
) {
|
||||
self.url = url
|
||||
self.content = content
|
||||
self.placeholder = placeholder
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if let image {
|
||||
content(Image(uiImage: image))
|
||||
} else {
|
||||
placeholder()
|
||||
.task {
|
||||
await loadImage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadImage() async {
|
||||
guard let url, !isLoading else { return }
|
||||
|
||||
isLoading = true
|
||||
defer { isLoading = false }
|
||||
|
||||
// Configure URLCache if needed
|
||||
configureURLCache()
|
||||
|
||||
do {
|
||||
let (data, _) = try await URLSession.shared.data(from: url)
|
||||
if let uiImage = UIImage(data: data) {
|
||||
await MainActor.run {
|
||||
image = uiImage
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("Failed to load image: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
private func configureURLCache() {
|
||||
let cache = URLCache.shared
|
||||
if cache.diskCapacity < 50_000_000 {
|
||||
URLCache.shared = URLCache(
|
||||
memoryCapacity: 10_000_000, // 10 MB
|
||||
diskCapacity: 50_000_000 // 50 MB
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Convenience Initializers
|
||||
|
||||
extension CachedAsyncImage where Content == Image, Placeholder == Color {
|
||||
init(url: URL?) {
|
||||
self.init(
|
||||
url: url,
|
||||
content: { $0.resizable() },
|
||||
placeholder: { Color.gray.opacity(0.2) }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user