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

150 lines
5.1 KiB
Swift

// Created by AI on 2025-10-11.
import UIKit
import Foundation
class EPImageUploader {
init() {}
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)
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)"
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
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)
}
}
}
private func parseUploadURL(_ location: String, customDomain: String) -> String {
let components = location.components(separatedBy: ".com/")
if components.count == 2 {
return "\(customDomain)/\(components[1])"
}
return location
}
}