如何在 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 fireSessionManager
和URLSessionConfiguration
具有 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 5.0.0-beta.3 (Swift 5) 上传图片(多部分)
如何在 multiformData 的 alamofire 中上传文件?