Files
real-e-party-iOS/YuMi/E-P/Common/EPImageUploader.swift
edwinQQQ 7626eb8351 feat: 添加动态发布功能及相关文档
主要变更:
1. 新增 EPImageUploader.swift 和 EPProgressHUD.swift,提供图片批量上传和进度显示功能。
2. 新建 EPMomentAPISwiftHelper.swift,封装动态 API 的 Swift 版本。
3. 更新 EPMomentPublishViewController,集成新上传功能并实现发布成功通知。
4. 创建多个文档,包括实施报告、检查清单和快速使用指南,详细记录功能实现和使用方法。
5. 更新 Bridging Header,确保 Swift 和 Objective-C 代码的互操作性。

此功能旨在提升用户体验,简化动态发布流程,并提供清晰的文档支持。
2025-10-11 17:16:30 +08:00

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

//
// 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("图片压缩失败")
}
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
}
}