167 lines
6.2 KiB
Swift
167 lines
6.2 KiB
Swift
import Foundation
|
||
import UIKit
|
||
|
||
/// 图片上传服务,封装了图片上传和进度跟踪功能
|
||
public class ImageUploadService {
|
||
|
||
// MARK: - Shared Instance
|
||
|
||
public static let shared = ImageUploadService()
|
||
|
||
// MARK: - Properties
|
||
|
||
private let uploader: ImageUploaderGetID
|
||
|
||
// MARK: - Initialization
|
||
|
||
public init(uploader: ImageUploaderGetID = ImageUploaderGetID()) {
|
||
self.uploader = uploader
|
||
}
|
||
|
||
// MARK: - Public Methods
|
||
|
||
/// 上传图片并返回上传结果
|
||
/// - Parameters:
|
||
/// - image: 要上传的图片
|
||
/// - progressHandler: 上传进度回调 (0.0 到 1.0)
|
||
/// - completion: 完成回调,返回上传结果或错误
|
||
public func uploadImage(
|
||
_ image: UIImage,
|
||
progress progressHandler: @escaping (ImageUploadService.UploadProgress) -> Void,
|
||
completion: @escaping (Result<ImageUploaderGetID.UploadResult, Error>) -> Void
|
||
) {
|
||
uploader.uploadImage(
|
||
image,
|
||
progress: { progress in
|
||
let progressInfo = ImageUploadService.UploadProgress(
|
||
current: Int(progress * 100),
|
||
total: 100,
|
||
progress: progress,
|
||
isOriginal: true
|
||
)
|
||
DispatchQueue.main.async {
|
||
progressHandler(progressInfo)
|
||
}
|
||
},
|
||
completion: { result in
|
||
DispatchQueue.main.async {
|
||
completion(result)
|
||
}
|
||
}
|
||
)
|
||
}
|
||
|
||
/// 上传压缩图片并返回上传结果
|
||
/// - Parameters:
|
||
/// - image: 要上传的图片
|
||
/// - compressionQuality: 压缩质量 (0.0 到 1.0)
|
||
/// - progressHandler: 上传进度回调 (0.0 到 1.0)
|
||
/// - completion: 完成回调,返回上传结果或错误
|
||
public func uploadCompressedImage(
|
||
_ image: UIImage,
|
||
compressionQuality: CGFloat = 0.5,
|
||
progress progressHandler: @escaping (ImageUploadService.UploadProgress) -> Void,
|
||
completion: @escaping (Result<ImageUploaderGetID.UploadResult, Error>) -> Void
|
||
) {
|
||
guard let compressedImage = image.jpegData(compressionQuality: compressionQuality).flatMap(UIImage.init(data:)) else {
|
||
completion(.failure(NSError(domain: "com.wake.upload", code: -1, userInfo: [NSLocalizedDescriptionKey: "图片压缩失败"])))
|
||
return
|
||
}
|
||
|
||
uploadImage(
|
||
compressedImage,
|
||
progress: progressHandler,
|
||
completion: completion
|
||
)
|
||
}
|
||
|
||
/// 上传原图和压缩图
|
||
/// - Parameters:
|
||
/// - image: 原始图片
|
||
/// - compressionQuality: 压缩质量 (0.0 到 1.0)
|
||
/// - progressHandler: 上传进度回调
|
||
/// - completion: 完成回调,返回原始图和压缩图的上传结果
|
||
public func uploadOriginalAndCompressedImage(
|
||
_ image: UIImage,
|
||
compressionQuality: CGFloat = 0.5,
|
||
progress progressHandler: @escaping (ImageUploadService.UploadProgress) -> Void,
|
||
completion: @escaping (Result<ImageUploadService.UploadResults, Error>) -> Void
|
||
) {
|
||
// 上传原图
|
||
uploadImage(image, progress: { progress in
|
||
let originalProgress = ImageUploadService.UploadProgress(
|
||
current: Int(progress.progress * 100),
|
||
total: 200, // 总进度为200(原图100 + 压缩图100)
|
||
progress: progress.progress * 0.5, // 原图占50%
|
||
isOriginal: true
|
||
)
|
||
progressHandler(originalProgress)
|
||
}) { [weak self] originalResult in
|
||
guard let self = self else { return }
|
||
|
||
switch originalResult {
|
||
case .success(let originalUploadResult):
|
||
// 原图上传成功,上传压缩图
|
||
self.uploadCompressedImage(
|
||
image,
|
||
compressionQuality: compressionQuality,
|
||
progress: { progress in
|
||
let compressedProgress = ImageUploadService.UploadProgress(
|
||
current: 100 + Int(progress.progress * 100), // 从100开始
|
||
total: 200, // 总进度为200(原图100 + 压缩图100)
|
||
progress: 0.5 + (progress.progress * 0.5), // 压缩图占后50%
|
||
isOriginal: false
|
||
)
|
||
progressHandler(compressedProgress)
|
||
},
|
||
completion: { compressedResult in
|
||
switch compressedResult {
|
||
case .success(let compressedUploadResult):
|
||
let results = ImageUploadService.UploadResults(
|
||
original: originalUploadResult,
|
||
compressed: compressedUploadResult
|
||
)
|
||
completion(.success(results))
|
||
|
||
case .failure(let error):
|
||
completion(.failure(error))
|
||
}
|
||
}
|
||
)
|
||
|
||
case .failure(let error):
|
||
completion(.failure(error))
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - Supporting Types
|
||
|
||
/// 上传进度信息
|
||
public struct UploadProgress {
|
||
public let current: Int
|
||
public let total: Int
|
||
public let progress: Double
|
||
public let isOriginal: Bool
|
||
|
||
public init(current: Int, total: Int, progress: Double, isOriginal: Bool) {
|
||
self.current = current
|
||
self.total = total
|
||
self.progress = progress
|
||
self.isOriginal = isOriginal
|
||
}
|
||
}
|
||
|
||
/// 上传结果,包含原图和压缩图的上传信息
|
||
public struct UploadResults {
|
||
public let original: ImageUploaderGetID.UploadResult
|
||
public let compressed: ImageUploaderGetID.UploadResult
|
||
|
||
public init(original: ImageUploaderGetID.UploadResult,
|
||
compressed: ImageUploaderGetID.UploadResult) {
|
||
self.original = original
|
||
self.compressed = compressed
|
||
}
|
||
}
|
||
}
|