fix FlexImage

This commit is contained in:
anlicheng 2025-04-15 15:49:05 +08:00
parent 9f6f3eb6b2
commit 6b3273ad2f

View File

@ -28,11 +28,9 @@ struct FlexImage: View {
let cacheManager = CacheManager.shared
if let data = cacheManager.readFileContents(urlString: urlString) {
print("url: \(urlString), hit cache")
self.mode = .local(data)
} else {
Task.detached {
await cacheManager.preloadImage(url: urlString)
}
self.mode = .remote(urlString)
}
}
@ -40,7 +38,7 @@ struct FlexImage: View {
var body: some View {
switch self.mode {
case .remote(let url):
AsyncImage(url: URL(string: url)) { phase in
FlexAsyncImage(url: URL(string: url)) { phase in
switch phase {
case .empty:
ProgressView()
@ -50,7 +48,7 @@ struct FlexImage: View {
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.clipped()
default:
case .failure:
Image(placeholder)
.resizable()
.aspectRatio(contentMode: .fill)
@ -72,28 +70,16 @@ struct FlexImage: View {
}
}
}
}
class ImageCache {
static let shared = ImageCache()
private let cache = NSCache<NSURL, UIImage>()
func image(for url: URL) -> UIImage? {
cache.object(forKey: url as NSURL)
}
func cacheImage(_ image: UIImage, for url: URL) {
cache.setObject(image, forKey: url as NSURL)
}
}
enum FlexImagePhase {
case empty
case success(Image)
case failure(Error)
case failure
}
struct MyAsyncImage<Content: View>: View {
struct FlexAsyncImage<Content: View>: View {
let url: URL?
@State private var phase: FlexImagePhase = .empty
@ViewBuilder let content: (FlexImagePhase) -> Content
@ -110,22 +96,27 @@ struct MyAsyncImage<Content: View>: View {
return
}
let cacheManager = CacheManager.shared
phase = .empty
do {
if let cachedImage = ImageCache.shared.image(for: url) {
if let data = cacheManager.readFileContents(urlString: url.absoluteString),
let cachedImage = await decodeImageData(data) {
phase = .success(Image(uiImage: cachedImage))
return
}
let (data, _) = try await URLSession.shared.data(from: url)
if let image = await decodeImageData(data) {
ImageCache.shared.cacheImage(image, for: url)
let cacheFilename = cacheManager.getCacheFileName(url: url)
try? cacheManager.saveCacheFile(filename: cacheFilename, data: data)
phase = .success(Image(uiImage: image))
} else {
phase = .empty
}
} catch {
phase = .failure(error)
phase = .failure
}
}
}
@ -137,24 +128,6 @@ struct MyAsyncImage<Content: View>: View {
}
}
// 使
struct ContentView: View {
var body: some View {
MyAsyncImage(url: URL(string: "https://lain.bgm.tv/pic/cover/l/60/fe/358801_WuBx6.jpg")) { phase in
switch phase {
case .empty:
ProgressView()
case .success(let image):
image
.resizable()
.scaledToFit()
case .failure(let error):
Text("Error: \(error.localizedDescription)")
}
}
}
}
#Preview {
ContentView()
FlexImage(urlString: "https://lain.bgm.tv/pic/cover/l/60/fe/358801_WuBx6.jpg", width: 80, height: 80, placeholder: "ph_img_big")
}