项目中用到了阿里云对象存储,就封装了四种上传方式,按数量分为单图和多图上传,上传方式分为同步和异步上传。
// 异步上传
func uploadImageAsync(image: UIImage,
uploadProgress: @escaping OSSNetworkingUploadProgressBlock,
uploadBlock: @escaping uploadImageBlock,
uploadFail: @escaping uploadImageFail) {
let imageName = imageNameWithCurrentTimescamp()
let put = OSSPutObjectRequest()
put.bucketName = bucketName
put.objectKey = imageName
guard let data = image.wcSessionCompress()?.jpegData(compressionQuality: 1) else { return }
put.uploadingData = data
put.uploadProgress = {bytesSent, totalByteSent, totalBytesExpectedToSend in
uploadProgress(bytesSent, totalByteSent, totalBytesExpectedToSend)
}
put.contentType = "image/jpeg"
let putTask = client.putObject(put)
putTask.continue({ (task) -> Any? in
do {
try self.client.doesObjectExist(inBucket: ThridPartyMarcos.AliOSS_BucketName.rawValue, objectKey: imageName)
let url = "https://\(self.startPoint)/\(imageName)"
uploadBlock(url)
} catch {
kLog(message: "上传失败")
if let error = putTask.error {
uploadFail(error)
}
}
return nil
}, cancellationToken: nil)
}
// 同步上传
func uploadImageSync(_ image: UIImage,
uploadProgress: @escaping OSSNetworkingUploadProgressBlock,
uploadBlock: @escaping uploadImageBlock,
uploadFail: @escaping uploadImageFail) {
let imageName = imageNameWithCurrentTimescamp()
let put = OSSPutObjectRequest()
put.bucketName = bucketName
put.objectKey = imageName
guard let data = image.wcSessionCompress()?.jpegData(compressionQuality: 1) else { return }
put.uploadingData = data
put.uploadProgress = {bytesSent, totalByteSent, totalBytesExpectedToSend in
uploadProgress(bytesSent, totalByteSent, totalBytesExpectedToSend)
}
put.contentType = "image/jpeg"
let putTask = client.putObject(put)
putTask.waitUntilFinished()
putTask.continue({ (task) -> Any? in
do {
try self.client.doesObjectExist(inBucket: self.bucketName, objectKey: imageName)
let url = "https://\(self.startPoint)/\(imageName)"
uploadBlock(url)
} catch {
kLog(message: "上传失败")
if let error = putTask.error {
uploadFail(error)
}
}
return nil
}, cancellationToken: nil)
}
/// 同步上传多张图片
func uploadImagesSync(_ images: [UIImage],
uploadProgress: @escaping OSSNetworkingUploadProgressBlock,
uploadBlock: @escaping uploadImagesBlock,
uploadFail: @escaping uploadImageFail) {
var imageUrls: [String] = []
for image in images {
let imageName = imageNameWithCurrentTimescamp()
let put = OSSPutObjectRequest()
put.bucketName = bucketName
put.objectKey = imageName
guard let data = image.wcSessionCompress()?.jpegData(compressionQuality: 1) else { return }
put.uploadingData = data
put.uploadProgress = {bytesSent, totalByteSent, totalBytesExpectedToSend in
uploadProgress(bytesSent, totalByteSent, totalBytesExpectedToSend)
}
put.contentType = "image/jpeg"
let putTask = client.putObject(put)
putTask.waitUntilFinished()
putTask.continue({ (task) -> Any? in
do {
try self.client.doesObjectExist(inBucket: self.bucketName, objectKey: imageName)
let url = "https://\(self.startPoint)/\(imageName)"
imageUrls.append(url)
/// 为什么加 imageUrls?.count == images.count ?
/// 只有所有图片都上传成功才视作上传任务完成
if image == images.last && imageUrls.count == images.count {
//上传最后一张图片结束
uploadBlock(imageUrls)
}
} catch {
kLog(message: "上传失败")
if let error = putTask.error {
uploadFail(error)
}
}
return nil
}, cancellationToken: nil)
}
}
/// 异步上传多张图片
func uploadAsyncImages(_ images: [UIImage],
uploadProgress: @escaping OSSNetworkingUploadProgressBlock,
uploadBlock: @escaping uploadImagesBlock,
uploadFail: @escaping uploadImageFail) {
let group = DispatchGroup()
var imageModelArray: [uploadImageAsyncModel] = []
for index in 0..<images.count {
let image = images[index]
var model = uploadImageAsyncModel(index: index, url: "")
let imageName = imageNameWithCurrentTimescamp()
let put = OSSPutObjectRequest()
put.bucketName = bucketName
put.objectKey = imageName
guard let data = image.wcSessionCompress()?.jpegData(compressionQuality: 1) else { return }
put.uploadingData = data
put.uploadProgress = {bytesSent, totalByteSent, totalBytesExpectedToSend in
uploadProgress(bytesSent, totalByteSent, totalBytesExpectedToSend)
}
put.contentType = "image/jpeg"
let putTask = client.putObject(put)
group.enter()
putTask.continue({ (task) -> Any? in
do {
try self.client.doesObjectExist(inBucket: self.bucketName, objectKey: imageName)
let url = "https://\(self.startPoint)/\(imageName)"
model.url = url
imageModelArray.append(model)
group.leave()
} catch {
if let error = putTask.error {
uploadFail(error)
}
imageModelArray.append(model)
group.leave()
}
return nil
}, cancellationToken: nil)
}
group.notify(queue: DispatchQueue.main) {
//图片上传结束,图片排序
if imageModelArray.count != images.count {
return
} else {
let sortedArray = imageModelArray.sorted {
return $0.index < $1.index
}
var imageUrls: [String] = []
for model in sortedArray {
if model.url.isEmpty {
break
} else {
imageUrls.append(model.url)
}
}
if imageUrls.count == images.count {
//返回图片数组url
uploadBlock(imageUrls)
}
}
}
}
//以时间戳命名图片名称
private func imageNameWithCurrentTimescamp() -> String {
let timeInterval: TimeInterval = Date().timeIntervalSince1970
let millisecond = CLongLong(round(timeInterval*1000))
var subFolder: String = ""
switch imageFolderType {
case .daily:
subFolder = "ios/daily"
case .post:
subFolder = "ios/post"
default:
subFolder = "ios/other"
}
let imageName = "\(subFolder)/\(millisecond).jpeg"
return imageName
}