Files
real-e-party-iOS/YuMi/E-P/Common/EPSDKManager.swift
2025-10-17 14:52:29 +08:00

243 lines
7.1 KiB
Swift

// Created by AI on 2025-10-11.
import Foundation
@objc class EPSDKManager: NSObject, QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate {
// MARK: - Singleton
@objc static let shared = EPSDKManager()
// MARK: - Properties
private var qcloudConfig: EPQCloudConfig?
private var isQCloudInitializing = false
private var qcloudInitCallbacks: [(Bool, String?) -> Void] = []
private var credentialFenceQueue: QCloudCredentailFenceQueue?
private let lock = NSLock()
private let uploader = EPImageUploader()
// MARK: - Initialization
private override init() {
super.init()
}
// MARK: - Public API ()
@objc func uploadImages(
_ images: [UIImage],
progress: @escaping (Int, Int) -> Void,
success: @escaping ([[String: Any]]) -> Void,
failure: @escaping (String) -> Void
) {
guard !images.isEmpty else {
success([])
return
}
ensureQCloudReady { [weak self] isReady, errorMsg in
guard let self = self, isReady else {
DispatchQueue.main.async {
failure(errorMsg ?? YMLocalizedString("error.qcloud_init_failed"))
}
return
}
self.uploader.performBatchUpload(
images,
bucket: self.qcloudConfig?.bucket ?? "",
customDomain: self.qcloudConfig?.customDomain ?? "",
progress: progress,
success: success,
failure: failure
)
}
}
@objc func isQCloudReady() -> Bool {
lock.lock()
defer { lock.unlock() }
guard let config = qcloudConfig else {
return false
}
return !config.isExpired
}
// MARK: - Internal Methods
private func ensureQCloudReady(completion: @escaping (Bool, String?) -> Void) {
if isQCloudReady() {
completion(true, nil)
return
}
initializeQCloud(completion: completion)
}
private func initializeQCloud(completion: @escaping (Bool, String?) -> Void) {
lock.lock()
if isQCloudInitializing {
qcloudInitCallbacks.append(completion)
lock.unlock()
return
}
if let config = qcloudConfig, !config.isExpired {
lock.unlock()
completion(true, nil)
return
}
isQCloudInitializing = true
qcloudInitCallbacks.append(completion)
lock.unlock()
Api.getQCloudInfo { [weak self] (data, code, msg) in
guard let self = self else { return }
self.lock.lock()
if code == 200,
let dict = data?.data as? [String: Any],
let config = EPQCloudConfig(dictionary: dict) {
self.qcloudConfig = config
self.configureQCloudSDK(with: config)
self.isQCloudInitializing = false
let callbacks = self.qcloudInitCallbacks
self.qcloudInitCallbacks.removeAll()
self.lock.unlock()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
callbacks.forEach { $0(true, nil) }
}
} else {
self.isQCloudInitializing = false
let callbacks = self.qcloudInitCallbacks
self.qcloudInitCallbacks.removeAll()
self.lock.unlock()
let errorMsg = msg ?? YMLocalizedString("error.qcloud_config_failed")
DispatchQueue.main.async {
callbacks.forEach { $0(false, errorMsg) }
}
}
}
}
private func configureQCloudSDK(with config: EPQCloudConfig) {
let configuration = QCloudServiceConfiguration()
configuration.appID = config.appId
let endpoint = QCloudCOSXMLEndPoint()
endpoint.regionName = config.region
endpoint.useHTTPS = true
if config.accelerate == 1 {
endpoint.suffix = "cos.accelerate.myqcloud.com"
}
configuration.endpoint = endpoint
configuration.signatureProvider = self
QCloudCOSXMLService.registerDefaultCOSXML(with: configuration)
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(with: configuration)
credentialFenceQueue = QCloudCredentailFenceQueue()
credentialFenceQueue?.delegate = self
}
// MARK: - QCloudSignatureProvider Protocol
func signature(
with fields: QCloudSignatureFields,
request: QCloudBizHTTPRequest,
urlRequest: NSMutableURLRequest,
compelete: @escaping QCloudHTTPAuthentationContinueBlock
) {
guard let config = qcloudConfig else {
let error = NSError(domain: "com.yumi.qcloud", code: -1,
userInfo: [NSLocalizedDescriptionKey: YMLocalizedString("error.qcloud_config_not_initialized")])
compelete(nil, error)
return
}
let credential = QCloudCredential()
credential.secretID = config.secretId
credential.secretKey = config.secretKey
credential.token = config.sessionToken
credential.startDate = Date(timeIntervalSince1970: TimeInterval(config.startTime))
credential.expirationDate = Date(timeIntervalSince1970: TimeInterval(config.expireTime))
let creator = QCloudAuthentationV5Creator(credential: credential)
let signature = creator?.signature(forData: urlRequest)
compelete(signature, nil)
}
// MARK: - QCloudCredentailFenceQueueDelegate Protocol
func fenceQueue(
_ queue: QCloudCredentailFenceQueue,
requestCreatorWithContinue continueBlock: @escaping QCloudCredentailFenceQueueContinue
) {
guard let config = qcloudConfig else {
let error = NSError(domain: "com.yumi.qcloud", code: -1,
userInfo: [NSLocalizedDescriptionKey: YMLocalizedString("error.qcloud_config_not_initialized")])
continueBlock(nil, error)
return
}
let credential = QCloudCredential()
credential.secretID = config.secretId
credential.secretKey = config.secretKey
credential.token = config.sessionToken
credential.startDate = Date(timeIntervalSince1970: TimeInterval(config.startTime))
credential.expirationDate = Date(timeIntervalSince1970: TimeInterval(config.expireTime))
let creator = QCloudAuthentationV5Creator(credential: credential)
continueBlock(creator, nil)
}
}