Files
e-party-iOS/yana/Utils/COSManager.swift
edwinQQQ 9a49d591c3 feat: 添加腾讯云COS Token管理功能及相关视图更新
- 在APIEndpoints.swift中新增tcToken端点以支持腾讯云COS Token获取。
- 在APIModels.swift中新增TcTokenRequest和TcTokenResponse模型,处理Token请求和响应。
- 在COSManager.swift中实现Token的获取、缓存和过期管理逻辑,提升API请求的安全性。
- 在LanguageSettingsView中添加调试功能,允许测试COS Token获取。
- 在多个视图中更新状态管理和导航逻辑,确保用户体验一致性。
- 在FeedFeature和HomeFeature中优化状态管理,简化视图逻辑。
2025-07-18 20:50:25 +08:00

138 lines
4.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 Foundation
import ComposableArchitecture
// MARK: - COS
/// COS
///
/// COS
/// - Token
/// -
/// -
@MainActor
class COSManager: ObservableObject {
static let shared = COSManager()
private init() {}
// MARK: - Token
/// Token
private var cachedToken: TcTokenData?
private var tokenExpirationDate: Date?
/// COS Token
/// - Parameter apiService: API
/// - Returns: Token nil
func getToken(apiService: any APIServiceProtocol & Sendable) async -> TcTokenData? {
//
if let cached = cachedToken, let expiration = tokenExpirationDate, Date() < expiration {
debugInfoSync("🔐 使用缓存的 COS Token")
return cached
}
//
clearCachedToken()
// Token
debugInfoSync("🔐 开始请求腾讯云 COS Token...")
do {
let request = TcTokenRequest()
let response: TcTokenResponse = try await apiService.request(request)
guard response.code == 200, let tokenData = response.data else {
debugInfoSync("❌ COS Token 请求失败: \(response.message)")
return nil
}
// Token
cachedToken = tokenData
tokenExpirationDate = tokenData.expirationDate
debugInfoSync("✅ COS Token 获取成功")
debugInfoSync(" - 存储桶: \(tokenData.bucket)")
debugInfoSync(" - 地域: \(tokenData.region)")
debugInfoSync(" - 过期时间: \(tokenData.expirationDate)")
debugInfoSync(" - 剩余时间: \(tokenData.remainingTime)")
return tokenData
} catch {
debugInfoSync("❌ COS Token 请求异常: \(error.localizedDescription)")
return nil
}
}
/// Token
/// - Parameter tokenData: Token
private func cacheToken(_ tokenData: TcTokenData) async {
cachedToken = tokenData
// expiration ISO 8601
if let expirationDate = ISO8601DateFormatter().date(from: String(tokenData.expireTime)) {
// 5
tokenExpirationDate = expirationDate.addingTimeInterval(-300)
} else {
// 1
tokenExpirationDate = Date().addingTimeInterval(3600)
}
debugInfoSync("💾 COS Token 已缓存,过期时间: \(tokenExpirationDate?.description ?? "未知")")
}
/// Token
private func clearCachedToken() {
cachedToken = nil
tokenExpirationDate = nil
debugInfoSync("🗑️ 清除缓存的 COS Token")
}
/// Token
func refreshToken(apiService: any APIServiceProtocol & Sendable) async -> TcTokenData? {
clearCachedToken()
return await getToken(apiService: apiService)
}
// MARK: -
/// 访 Token
var token: TcTokenData? { cachedToken }
// MARK: -
/// Token
func getTokenStatus() -> String {
if let cached = cachedToken, let expiration = tokenExpirationDate {
let isExpired = Date() >= expiration
return "Token 状态: \(isExpired ? "已过期" : "有效"), 过期时间: \(expiration)"
} else {
return "Token 状态: 未缓存"
}
}
}
// MARK: -
extension COSManager {
/// Token
func testTokenRetrieval(apiService: any APIServiceProtocol & Sendable) async {
#if DEBUG
debugInfoSync("\n🧪 开始测试腾讯云 COS Token 获取功能")
let token = await getToken(apiService: apiService)
if let tokenData = token {
debugInfoSync("✅ Token 获取成功")
debugInfoSync(" bucket: \(tokenData.bucket)")
debugInfoSync(" Expiration: \(tokenData.expireTime)")
debugInfoSync(" Token: \(tokenData.sessionToken.prefix(20))...")
debugInfoSync(" SecretId: \(tokenData.secretId.prefix(20))...")
} else {
debugInfoSync("❌ Token 获取失败")
}
debugInfoSync("📊 Token 状态: \(getTokenStatus())")
debugInfoSync("✅ 腾讯云 COS Token 测试完成\n")
#endif
}
}