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

164 lines
6.1 KiB
Plaintext
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.

//
// EPImageUploader.swift
// YuMi
//
// Created by AI on 2025-10-11.
//
import UIKit
import Foundation
/// 图片批量上传工具(纯 Swift 内部类,直接使用 QCloudCOSXML SDK
/// 不对外暴露,由 EPSDKManager 内部调用
class EPImageUploader {
init() {}
/// 批量上传图片(内部方法)
/// - Parameters:
/// - images: 要上传的图片数组
/// - bucket: QCloud bucket 名称
/// - customDomain: 自定义域名
/// - progress: 进度回调 (已上传数, 总数)
/// - success: 成功回调
/// - failure: 失败回调
func performBatchUpload(
_ images: [UIImage],
bucket: String,
customDomain: String,
progress: @escaping (Int, Int) -> Void,
success: @escaping ([[String: Any]]) -> Void,
failure: @escaping (String) -> Void
) {
let total = images.count
let queue = DispatchQueue(label: "com.yumi.imageupload", attributes: .concurrent)
let semaphore = DispatchSemaphore(value: 3) // 最多同时上传 3 张
var uploadedCount = 0
var resultList: [[String: Any]] = []
var hasError = false
let lock = NSLock()
for (_, image) in images.enumerated() {
queue.async {
semaphore.wait()
// 检查是否已经失败
lock.lock()
if hasError {
lock.unlock()
semaphore.signal()
return
}
lock.unlock()
// 压缩图片
guard let imageData = image.jpegData(compressionQuality: 0.5) else {
lock.lock()
hasError = true
lock.unlock()
semaphore.signal()
DispatchQueue.main.async {
failure(YMLocalizedString("error.image_compress_failed"))
}
return
}
// 获取图片格式
let format = UIImage.getImageType(withImageData: imageData) ?? "jpeg"
// 生成文件名
let uuid = NSString.createUUID()
let fileName = "image/\(uuid).\(format)"
// 直接使用 QCloud SDK 上传
let request = QCloudCOSXMLUploadObjectRequest<AnyObject>()
request.bucket = bucket
request.object = fileName
request.body = imageData as NSData
// 监听上传进度(可选)
request.sendProcessBlock = { bytesSent, totalBytesSent, totalBytesExpectedToSend in
// 单个文件的上传进度(当前不使用)
}
// 监听上传结果
request.finishBlock = { [weak self] result, error in
guard let self = self else {
semaphore.signal()
return
}
if let error = error {
// 上传失败
lock.lock()
if !hasError {
hasError = true
lock.unlock()
semaphore.signal()
DispatchQueue.main.async {
failure(error.localizedDescription)
}
} else {
lock.unlock()
semaphore.signal()
}
} else if let result = result as? QCloudUploadObjectResult {
// 上传成功
lock.lock()
if !hasError {
uploadedCount += 1
// 解析上传 URL参考 UploadFile.m line 217-223
let uploadedURL = self.parseUploadURL(result.location, customDomain: customDomain)
let imageInfo: [String: Any] = [
"resUrl": uploadedURL,
"width": image.size.width,
"height": image.size.height,
"format": format
]
resultList.append(imageInfo)
let currentUploaded = uploadedCount
lock.unlock()
// 进度回调
DispatchQueue.main.async {
progress(currentUploaded, total)
}
// 全部完成
if currentUploaded == total {
DispatchQueue.main.async {
success(resultList)
}
}
} else {
lock.unlock()
}
semaphore.signal()
} else {
semaphore.signal()
}
}
// 执行上传
QCloudCOSTransferMangerService.defaultCOSTransferManager().uploadObject(request)
}
}
}
/// 解析上传返回的 URL参考 UploadFile.m line 217-223
/// - Parameters:
/// - location: QCloud 返回的原始 URL
/// - customDomain: 自定义域名
/// - Returns: 解析后的 URL
private func parseUploadURL(_ location: String, customDomain: String) -> String {
let components = location.components(separatedBy: ".com/")
if components.count == 2 {
return "\(customDomain)/\(components[1])"
}
return location
}
}