fix FlexImage
This commit is contained in:
parent
9f6f3eb6b2
commit
6b3273ad2f
@ -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")
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user