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

Posted

技术标签:

【中文标题】如何在 alamofire 中同步上传图片?【英文标题】:How to do image upload in alamofire Synchronously ? 【发布时间】:2017-06-27 09:06:55 【问题描述】:

我正在使用 swift 3 和 Alamofire 4 。我想在 for 循环中上传 6 张图片,但 alamofire 上传请求异步运行。它的作用是先运行for循环,然后再上传。但我想等到我得到回复,然后再上传。我该怎么做?

【问题讨论】:

仅供参考 Alamofire 异步运行是有原因的。尝试同步运行上传(或任何网络请求)几乎总是一个糟糕的设计决定。 如果您担心网络连接太弱而无法同时处理多个上传(您应该这样做),那么还有其他方法(查看 alamo fire SessionManagerURLSessionConfiguration 具有 httpMaximumConnectionsPerHost 属性。 【参考方案1】:

您应该使用序列号DispatchQueue 按顺序运行您的图片上传。串行队列将确保一次只运行一个请求,并且下一个请求仅在前一个请求完成执行后开始。

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

【讨论】:

【参考方案2】:

模型类

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")
        
    


上传图片,首先确保将 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
    

【讨论】:

【参考方案3】:

您可以使用DispatchGroup 类。

DispatchGroup 允许工作的聚合同步。

您可以使用它们提交多个不同的工作项并跟踪 当它们全部完成时,即使它们可能在不同的平台上运行 排队。

当在 指定的任务已完成。

示例代码:

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.")

【讨论】:

以上是关于如何在 alamofire 中同步上传图片?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire (post) 上传图片?

如何使用 Alamofire 5.0.0-beta.3 (Swift 5) 上传图片(多部分)

如何在 multiformData 的 alamofire 中上传文件?

如何使用 Alamofire.upload 函数上传带有一些参数的图片或 wav 文件

alamofire上传带json参数的图片

Swift UI 和 Alamofire 图片上传