
- 修改COSManagerAdapter以支持新的TCCos组件,确保与腾讯云COS的兼容性。 - 在CreateFeedFeature中新增图片上传相关状态和Action,优化图片选择与上传逻辑。 - 更新CreateFeedView以整合图片上传功能,提升用户体验。 - 在多个视图中添加键盘状态管理,改善用户交互体验。 - 新增COS相关的测试文件,确保功能的正确性和稳定性。
202 lines
6.2 KiB
Swift
202 lines
6.2 KiB
Swift
import Foundation
|
||
import QCloudCOSXML
|
||
import ComposableArchitecture
|
||
|
||
// MARK: - COS 配置服务协议
|
||
|
||
/// COS 配置服务协议
|
||
public protocol COSConfigurationServiceProtocol: Sendable {
|
||
/// 初始化COS服务
|
||
func initializeCOSService(with tokenData: TcTokenData) async throws
|
||
|
||
/// 检查COS服务是否已初始化
|
||
func isCOSServiceInitialized() async -> Bool
|
||
|
||
/// 获取当前配置
|
||
func getCurrentConfiguration() async -> COSConfiguration?
|
||
|
||
/// 重置COS服务
|
||
func resetCOSService() async
|
||
}
|
||
|
||
// MARK: - COS 配置服务实现
|
||
|
||
/// COS 配置服务实现
|
||
public struct COSConfigurationService: COSConfigurationServiceProtocol {
|
||
private let configurationCache: ConfigurationCacheProtocol
|
||
|
||
public init(configurationCache: ConfigurationCacheProtocol = ConfigurationCache()) {
|
||
self.configurationCache = configurationCache
|
||
}
|
||
|
||
/// 初始化COS服务
|
||
public func initializeCOSService(with tokenData: TcTokenData) async throws {
|
||
// 检查是否已经初始化
|
||
if await isCOSServiceInitialized() {
|
||
debugInfoSync("✅ COS服务已初始化,跳过重复初始化")
|
||
return
|
||
}
|
||
|
||
do {
|
||
// 创建配置
|
||
let configuration = QCloudServiceConfiguration()
|
||
let endpoint = QCloudCOSXMLEndPoint()
|
||
|
||
// 设置地域
|
||
endpoint.regionName = tokenData.region
|
||
endpoint.useHTTPS = true
|
||
|
||
// 设置加速域名
|
||
if tokenData.accelerate {
|
||
endpoint.suffix = "cos.accelerate.myqcloud.com"
|
||
}
|
||
|
||
configuration.endpoint = endpoint
|
||
|
||
// 注册服务
|
||
QCloudCOSXMLService.registerDefaultCOSXML(with: configuration)
|
||
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(with: configuration)
|
||
|
||
// 缓存配置
|
||
let cosConfiguration = COSConfiguration(
|
||
region: tokenData.region,
|
||
bucket: tokenData.bucket,
|
||
accelerate: tokenData.accelerate,
|
||
customDomain: tokenData.customDomain,
|
||
useHTTPS: true
|
||
)
|
||
await configurationCache.cacheConfiguration(cosConfiguration)
|
||
|
||
debugInfoSync("✅ COS服务已初始化,region: \(tokenData.region)")
|
||
|
||
} catch {
|
||
debugErrorSync("❌ COS服务初始化失败: \(error.localizedDescription)")
|
||
throw COSError.configurationFailed(error.localizedDescription)
|
||
}
|
||
}
|
||
|
||
/// 检查COS服务是否已初始化
|
||
public func isCOSServiceInitialized() async -> Bool {
|
||
return await configurationCache.getCachedConfiguration() != nil
|
||
}
|
||
|
||
/// 获取当前配置
|
||
public func getCurrentConfiguration() async -> COSConfiguration? {
|
||
return await configurationCache.getCachedConfiguration()
|
||
}
|
||
|
||
/// 重置COS服务
|
||
public func resetCOSService() async {
|
||
await configurationCache.clearCachedConfiguration()
|
||
debugInfoSync("🔄 COS服务配置已重置")
|
||
}
|
||
}
|
||
|
||
// MARK: - 配置缓存协议
|
||
|
||
/// 配置缓存协议
|
||
public protocol ConfigurationCacheProtocol: Sendable {
|
||
/// 获取缓存的配置
|
||
func getCachedConfiguration() async -> COSConfiguration?
|
||
|
||
/// 缓存配置
|
||
func cacheConfiguration(_ configuration: COSConfiguration) async
|
||
|
||
/// 清除缓存的配置
|
||
func clearCachedConfiguration() async
|
||
}
|
||
|
||
// MARK: - 配置缓存实现
|
||
|
||
/// 配置缓存实现
|
||
public actor ConfigurationCache: ConfigurationCacheProtocol {
|
||
private var cachedConfiguration: COSConfiguration?
|
||
|
||
public init() {}
|
||
|
||
/// 获取缓存的配置
|
||
public func getCachedConfiguration() async -> COSConfiguration? {
|
||
return cachedConfiguration
|
||
}
|
||
|
||
/// 缓存配置
|
||
public func cacheConfiguration(_ configuration: COSConfiguration) async {
|
||
cachedConfiguration = configuration
|
||
debugInfoSync("💾 COS配置已缓存: \(configuration.region)")
|
||
}
|
||
|
||
/// 清除缓存的配置
|
||
public func clearCachedConfiguration() async {
|
||
cachedConfiguration = nil
|
||
debugInfoSync("🗑️ 清除缓存的 COS 配置")
|
||
}
|
||
}
|
||
|
||
// MARK: - TCA 依赖扩展
|
||
|
||
extension DependencyValues {
|
||
/// COS 配置服务依赖
|
||
public var cosConfigurationService: COSConfigurationServiceProtocol {
|
||
get { self[COSConfigurationServiceKey.self] }
|
||
set { self[COSConfigurationServiceKey.self] = newValue }
|
||
}
|
||
}
|
||
|
||
/// COS 配置服务依赖键
|
||
private enum COSConfigurationServiceKey: DependencyKey {
|
||
static let liveValue: COSConfigurationServiceProtocol = COSConfigurationService()
|
||
static let testValue: COSConfigurationServiceProtocol = MockCOSConfigurationService()
|
||
}
|
||
|
||
// MARK: - Mock 服务(用于测试)
|
||
|
||
/// Mock 配置服务(用于测试)
|
||
public struct MockCOSConfigurationService: COSConfigurationServiceProtocol {
|
||
public var initializeResult: Result<Void, Error> = .success(())
|
||
public var isInitializedResult: Bool = false
|
||
public var configurationResult: COSConfiguration? = nil
|
||
|
||
public init() {}
|
||
|
||
public func initializeCOSService(with tokenData: TcTokenData) async throws {
|
||
switch initializeResult {
|
||
case .success:
|
||
return
|
||
case .failure(let error):
|
||
throw error
|
||
}
|
||
}
|
||
|
||
public func isCOSServiceInitialized() async -> Bool {
|
||
return isInitializedResult
|
||
}
|
||
|
||
public func getCurrentConfiguration() async -> COSConfiguration? {
|
||
return configurationResult
|
||
}
|
||
|
||
public func resetCOSService() async {
|
||
// Mock 实现,无需实际操作
|
||
}
|
||
}
|
||
|
||
// MARK: - 扩展
|
||
|
||
extension COSConfiguration {
|
||
/// 构建完整的域名
|
||
public var fullDomain: String {
|
||
if !customDomain.isEmpty {
|
||
return customDomain
|
||
}
|
||
|
||
let baseDomain = "\(bucket).cos.\(region).myqcloud.com"
|
||
return accelerate ? "\(bucket).cos.accelerate.myqcloud.com" : baseDomain
|
||
}
|
||
|
||
/// 构建完整的URL前缀
|
||
public var urlPrefix: String {
|
||
let domain = fullDomain
|
||
let scheme = useHTTPS ? "https" : "http"
|
||
return "\(scheme)://\(domain)"
|
||
}
|
||
} |