♻️ Refactor watchOS content view
This commit is contained in:
103
ios/WatchRunner Watch App/Services/ImageLoader.swift
Normal file
103
ios/WatchRunner Watch App/Services/ImageLoader.swift
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// ImageLoader.swift
|
||||
// WatchRunner Watch App
|
||||
//
|
||||
// Created by LittleSheep on 2025/10/29.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
import KingfisherWebP
|
||||
import Combine
|
||||
|
||||
// MARK: - Image Loader
|
||||
|
||||
@MainActor
|
||||
class ImageLoader: ObservableObject {
|
||||
@Published var image: Image?
|
||||
@Published var errorMessage: String?
|
||||
@Published var isLoading = false
|
||||
|
||||
private var dataTask: URLSessionDataTask?
|
||||
private let session: URLSession
|
||||
|
||||
init(session: URLSession = .shared) {
|
||||
self.session = session
|
||||
}
|
||||
|
||||
deinit {
|
||||
dataTask?.cancel()
|
||||
}
|
||||
|
||||
func loadImage(from initialUrl: URL, token: String) async {
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
image = nil
|
||||
|
||||
do {
|
||||
// First request with Authorization header
|
||||
var request = URLRequest(url: initialUrl)
|
||||
request.setValue("AtField \(token)", forHTTPHeaderField: "Authorization")
|
||||
request.setValue("SolianWatch/1.0", forHTTPHeaderField: "User-Agent")
|
||||
|
||||
let (data, response) = try await session.data(for: request)
|
||||
|
||||
if let httpResponse = response as? HTTPURLResponse {
|
||||
if httpResponse.statusCode == 302, let redirectLocation = httpResponse.allHeaderFields["Location"] as? String, let redirectUrl = URL(string: redirectLocation) {
|
||||
print("[watchOS] Redirecting to: \(redirectUrl)")
|
||||
// Second request to the redirected URL (S3 signed URL) without Authorization header
|
||||
let (redirectData, _) = try await session.data(from: redirectUrl)
|
||||
if let uiImage = UIImage(data: redirectData) {
|
||||
self.image = Image(uiImage: uiImage)
|
||||
print("[watchOS] Image loaded successfully from redirect URL.")
|
||||
} else {
|
||||
// Try KingfisherWebP for WebP
|
||||
let processor = WebPProcessor.default // Correct usage
|
||||
if let kfImage = processor.process(item: .data(redirectData), options: KingfisherParsedOptionsInfo(
|
||||
[
|
||||
.processor(processor),
|
||||
.loadDiskFileSynchronously,
|
||||
.cacheOriginalImage
|
||||
]
|
||||
)) {
|
||||
self.image = Image(uiImage: kfImage)
|
||||
print("[watchOS] Image loaded successfully from redirect URL using KingfisherWebP.")
|
||||
} else {
|
||||
self.errorMessage = "Invalid image data from redirect (could not decode with KingfisherWebP)."
|
||||
}
|
||||
}
|
||||
} else if httpResponse.statusCode == 200 {
|
||||
if let uiImage = UIImage(data: data) {
|
||||
self.image = Image(uiImage: uiImage)
|
||||
print("[watchOS] Image loaded successfully from initial URL.")
|
||||
} else {
|
||||
// Try KingfisherWebP for WebP
|
||||
let processor = WebPProcessor.default // Correct usage
|
||||
if let kfImage = processor.process(item: .data(data), options: KingfisherParsedOptionsInfo(
|
||||
[
|
||||
.processor(processor),
|
||||
.loadDiskFileSynchronously,
|
||||
.cacheOriginalImage
|
||||
]
|
||||
)) {
|
||||
self.image = Image(uiImage: kfImage)
|
||||
print("[watchOS] Image loaded successfully from initial URL using KingfisherWebP.")
|
||||
} else {
|
||||
self.errorMessage = "Invalid image data (could not decode with KingfisherWebP)."
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.errorMessage = "HTTP Status Code: \(httpResponse.statusCode)"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = error.localizedDescription
|
||||
print("[watchOS] Image loading failed: \(error.localizedDescription)")
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
func cancel() {
|
||||
dataTask?.cancel()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user