Files
JetsonMediaIOS/Jetson Media/ui/AsyncImageView.swift
Spasol cb7294d722 Initial Create
基础框架实现
2025-08-16 23:45:52 +08:00

107 lines
3.8 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SwiftUI
struct AsyncImageView: View {
let url: String
let nums: [Int]
let index: Int
@State private var image: UIImage?
@State private var isLoading = false
@State private var error: Error?
//
private static var currentlyLoadingIndices: Set<Int> = []
private static let maxConcurrentLoads = 4
var body: some View {
Group {
if let image = image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
} else if isLoading {
ProgressView()
} else if error != nil {
VStack {
Image(systemName: "exclamationmark.triangle")
.foregroundColor(.red)
Text(error?.localizedDescription ?? "未知错误")
.font(.caption)
}
} else {
Color.gray.opacity(0.3)
}
}
.onAppear {
loadImage()
}
}
private func loadImage() {
//
guard !Self.currentlyLoadingIndices.contains(index),
Self.currentlyLoadingIndices.count < Self.maxConcurrentLoads else {
return
}
//
Self.currentlyLoadingIndices.insert(index)
isLoading = true
error = nil
// nums index
guard let decodeNum = nums[safe: index] else {
print("错误nums 中未找到索引 \(index) 对应的值,可能 API 数据不一致")
Self.currentlyLoadingIndices.remove(index)
return
}
print("调试信息:图片 URL: \(url), 解密参数 num: \(decodeNum), 索引: \(index)")
guard let imageUrl = URL(string: url) else {
self.error = NSError(domain: "无效的URL", code: 1, userInfo: nil)
isLoading = false
Self.currentlyLoadingIndices.remove(index)
return
}
//
URLSession.shared.dataTask(with: imageUrl) { data, response, error in
DispatchQueue.main.async {
//
Self.currentlyLoadingIndices.remove(index)
self.isLoading = false
if let error = error {
self.error = error
print("图片加载失败,错误: \(error.localizedDescription)")
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode),
let data = data, !data.isEmpty else {
self.error = NSError(domain: "无效响应", code: 2, userInfo: nil)
print("图片加载失败,无效响应或数据为空")
return
}
if let loadedImage = UIImage(data: data) {
print("图片加载成功,开始解密...")
let decodedImage = loadedImage.decodeImage(num: decodeNum)
self.image = decodedImage
print("解密完成,图片已更新")
} else {
self.error = NSError(domain: "图片数据解码失败", code: 4, userInfo: nil)
print("图片数据解码失败")
}
}
}.resume()
}
}
extension Array {
subscript(safe index: Int) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}