2022-05-06

对于上传阿里云多张图片长时间占用主线程导致界面假死现象处理记录

在阿里云上传图片时,官方指导调用都是类似这样:

创建单例管理类基本上没什么变化,一系列配置在弱网条件下算是能尽可能避免上传失败,当然也可以默认配置

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)

            }

        }

    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容