简体   繁体   English

如何在alamofire中同步上传图片?

[英]How to do image upload in alamofire Synchronously ?

Im using swift 3 and Alamofire 4 . 我使用swift 3和Alamofire 4。 I want to upload 6 images inside a for loop but alamofire upload request run asynchronously. 我想在for循环中上传6个图像,但是alamofire上传请求是异步运行的。 What it does is it runs for loop first and then the upload. 它的作用是先运行循环然后再运行上传。 But i want to wait until i get a response and then upload next. 但是我想等到我收到回复然后再上传。 How can i do this? 我怎样才能做到这一点?

You should use a serial DispatchQueue to run your image uploads sequentially. 您应该使用序列DispatchQueue按顺序运行图像上载。 The serial queue will ensure that only one request will be run at a time and the next one only starts when the previous one finished execution. 串行队列将确保一次只运行一个请求,而下一个请求仅在前一个请求完成执行时启动。

let serialQueue = DispatchQueue(label: "serialQueue")
for image in images {
    serialQueue.async{
       //upload image with Alamofire here
    }
}

Model Class 模型类

class MultipartUpdataData: NSObject
{
    var mediaData:Data!
    var mediaUploadKey:String!
    var fileName:String!
    var mimeType:String!
    override init()
    {

    }
    required   init(coder aDecoder: NSCoder) {

        if let mediaData = aDecoder.decodeObject(forKey: "mediaData") as? Data {

            self.mediaData = mediaData
        }
        if let mediaUploadKey = aDecoder.decodeObject(forKey: "mediaUploadKey") as? String {

            self.mediaUploadKey = mediaUploadKey
        }
        if let fileName = aDecoder.decodeObject(forKey: "fileName") as? String {

            self.fileName = fileName
        }
        if let mimeType = aDecoder.decodeObject(forKey: "mimeType") as? String {

            self.mimeType = mimeType
        }
    }
    open func encodeWithCoder(_ aCoder: NSCoder)
    {
        if let mediaData = self.mediaData{
            aCoder.encode(mediaData, forKey: "mediaData")
        }
        if let mediaUploadKey = self.mediaUploadKey {
            aCoder.encode(mediaUploadKey, forKey: "mediaUploadKey")
        }
        if let mimeType = self.mimeType {
            aCoder.encode(mimeType, forKey: "mimeType")
        }
        if let fileName = self.fileName {
            aCoder.encode(fileName, forKey: "fileName")
        }
    }

}

Upload Image, First make sure to append imageData into array then call this function like below:- 上传图片,首先确保将imageData附加到数组中然后调用此函数如下: -

 var uploadMediaList  = [MultipartUpdataData]()
for loop{
let multiObject  = MultipartUpdataData()
            multiObject.mediaData = self.pngImageData!
            multiObject.mimeType = "image/png"
            multiObject.mediaUploadKey = "profile_pic" //Replace this key with your existing key.
            let profileFilename = self.filename(Prefix: "profile", fileExtension: "png")
            multiObject.fileName = profileFilename
            uploadMediaList.append(multiObject)
}
self.upload(uploadMediaList)

func upload(multipartImages:[MultipartUpdataData]){
        let parameters:[String:String] = ["key":"value"]
        Alamofire.upload(
            multipartFormData: { multipartFormData in


                for mData in multipartImages!{
                    let pngImageData = mData.mediaData
                    let uploadfileNamekey = mData.mediaUploadKey
                    let fileName = mData.fileName!
                    let mimeType = mData.mimeType!
                    multipartFormData.append(pngImageData!, withName: uploadfileNamekey!, fileName: fileName, mimeType: mimeType)

                }
                for (key, value) in parameters {
                    multipartFormData.append(value.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue), allowLossyConversion: true)!, withName: key)
                }

        },
            to: "\(url)",
            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON { response in
                        let json = JSON(data: response.data!)

                    print("SUCSESS")

                    }
                case .failure(let encodingError):
                   print("ERORR")

                }
        }
        )
    }
//MARK:-filename-
    func filename(Prefix:String , fileExtension:String)-> String
    {
        let dateformatter=DateFormatter()
        dateformatter.dateFormat="MddyyHHmmss"
        let dateInStringFormated=dateformatter.string(from: NSDate() as Date )
        return  NSString(format: "%@_%@.%@", Prefix,dateInStringFormated,fileExtension) as String
    }

You can use DispatchGroup class. 您可以使用DispatchGroup类。

DispatchGroup allows for aggregate synchronization of work. DispatchGroup允许工作的聚合同步。

You can use them to submit multiple different work items and track when they all complete, even though they might run on different queues. 您可以使用它们提交多个不同的工作项并跟踪它们何时完成,即使它们可能在不同的队列上运行。

This behavior can be helpful when progress can't be made until all of the specified tasks are complete. 在完成所有指定任务之前无法进行此操作时,此行为很有用。

Sample code: 示例代码:

let dispatchGroup = DispatchGroup()

var i = 0
for element in yourImageArray {
    dispatchGroup.enter()
    i = i+1

    Alamofire.request("https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in
        print("Finished request \(i)")
        dispatchGroup.leave()
    }
}

dispatchGroup.notify(queue: .main) {
    print("Finished all requests.")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM