对于上传阿里云多张图片长时间占用主线程导致界面假死现象处理记录
在阿里云上传图片时,官方指导调用都是类似这样:
创建单例管理类基本上没什么变化,一系列配置在弱网条件下算是能尽可能避免上传失败,当然也可以默认配置
class OSSUploadManager: NSObject {
static let manager = OSSupLoadManager()
var client: OSSClient?
override init() {
super.init()
let endpoint = "找你后台要xxx"
let credential = OSSAuthCredentialProvider.init(authServerUrl: "找你后台要 https:xxxx.com")
let config = OSSClientConfiguration()
config.maxRetryCount = 2
config.timeoutIntervalForRequest = 60
config.timeoutIntervalForResource = 120
config.maxConcurrentRequestCount = 1
client = OSSClient.init(endpoint: endpoint, credentialProvider: credential, clientConfiguration: config)
OSSLog.enable()//开启日志
}
}
在上传回调时:一般这样调用了 waitUntilFinished() 导致图片上传未完成时阻塞主线程,多张图片下更加明显,引起程序假死现象
8044219-747a1aaa3f6d51bd.png
为了避免这个问题,我引用了 DispatchGroup() 是GCD的一项特性,可以把任务分组。这组任务完成后时,调用者会收到通知: 可将要并发执行的多个任务合并为一组,这样调用者就可以知道这些任务何时能全部执行完
extension OSSUploadManager {
/// 上传一组图片/ 单张图片
/// - Parameters:
/// - imgArray: 图片组
/// - success: 成功回调
/// - failure: 失败回调
func updateImages(_ imgArray: [UIImage?], success :@escaping ((_ imgUrls: [String]) -> ()), failure :@escaping ((_ msg: String) -> ()))) {
let group = DispatchGroup()
// 创建多列
let workingQueue = DispatchQueue(label: "request_queue")
var urlArray = [String]()
//是否是单张图片上传
let isSingleImg = imgArray.count == 1 ? true : false
for (index, image) in imgArray.enumerated() {
group.enter()//进入组
workingQueue.async {
//图片压缩处理
guard let data = image?.resetSizeOfImageData(maxSize: 800) else { return }
let request = OSSPutObjectRequest()
request.uploadingData = data
request.bucketName = "找你后台要"
let pathPrefix = "路径"
if isSingleImg {
request.objectKey = "\(pathPrefix).png"
}else {
//index 可做图片排序用
request.objectKey = "\(pathPrefix)/\(index).png"
}
request.uploadProgress = { (bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) -> Void in
print("bytesSent:\(bytesSent),totalBytesSent:\(totalBytesSent),totalBytesExpectedToSend:\(totalBytesExpectedToSend)");
}
let tasks = self.client?.putObject(request)
tasks?.continue({ (t) -> Any? in
if let error = t.error {
failure("图片上传失败")
print("图片上传失败:\(error)")
}else {
urlArray.append(request.objectKey)
print("图片上传成功!")
}
group.leave() //不论是成功或者失败,都离开组
return nil
})
}
}
group.notify(queue: workingQueue) {
success(urlArray)
}
}
}