如何在 Swift 4 中使用 Alamofire 上传具有其他参数的多个图像
Posted
技术标签:
【中文标题】如何在 Swift 4 中使用 Alamofire 上传具有其他参数的多个图像【英文标题】:How to upload multiple images with other parameters using Alamofire in Swift 4 【发布时间】:2018-07-19 10:56:05 【问题描述】:我正在使用Alamofire
向服务器发送请求。现在我必须使用其他参数将一组图像(多个图像)发送到服务器。我必须发送最多 4 张图片。请有人帮助我,如何解决这个任务。我检查了 *** 的解决方案,但所有解决方案都类似于将单个图像发送到服务器。但我想使用Alamofire
发送多个图像,因为我有图像数组。
这是我的代码
func clockOutFor(userId: NSNumber, projectId: NSNumber, taskId: NSNumber, latitude: CLLocationDegrees, longitude: CLLocationDegrees, deviceClockOutTime: String, actualEndTime: String, clockOutNetworkInfo: String, clockOutBatteryStatus: String, totalDistance: NSNumber, durationTime: String, customeLabel1: String, customeLabel2: String, customeLabel3: String, customeLabel4: String, customeLabel5: String, imageDataArray: NSArray, completionHandler: @escaping CompletionBlock ) -> Void
let parameter : Parameters = ["gs_userId":userId, "gs_taskId":taskId, "gs_project_id":projectId, "gs_actual_end":actualEndTime, "gs_actual_end_lattitude":latitude, "gs_actual_end_longitude":longitude, "gs_clockout_device_time":deviceClockOutTime, "gs_clockout_network_status":clockOutNetworkInfo, "gs_clockout_battery_status":clockOutBatteryStatus, "gs_distance":totalDistance, "gs_time_taken":durationTime, "gs_custom1_label":customeLabel1, "gs_custom1_labe2":customeLabel2, "gs_custom1_labe3":customeLabel3, "gs_custom1_labe4":customeLabel4, "gs_custom1_labe5":customeLabel5] as [String : AnyObject]
let url = "clockout-update"
let fullUrl = baseUrl?.appendingPathComponent(url)
let headers: HTTPHeaders = [
"Authorization" : "Bearer \(token!)",
"Accept": "application/json",
"Connection": "keep-alive",
"Content-type": "multipart/form-data"
]
if token != nil
Alamofire.upload(multipartFormData: multipartFormData in
for i in 0..<imageDataArray.count
let imageData1 = UIImageJPEGRepresentation(imageDataArray[i] as! UIImage, 1.0)!
multipartFormData.append(imageData1, withName: "morephoto[\(i)]" , fileName: "photo" + String(i) + ".jpg", mimeType: "image/jpeg")
for (key, value) in parameter
print("Key and Value = ",key, value)
if let data = (value as AnyObject).data(using: String.Encoding.utf8.rawValue)
multipartFormData.append(data, withName: key)
,
to: fullUrl!,method:HTTPMethod.post,
headers:headers, encodingCompletion: encodingResult in
switch encodingResult
case .success(let upload, _, _):
upload
.validate()
.responseJSON response in
print(response.request as Any) // original URL request
print(response.response as Any) // URL response
print(response.data as Any) // server data
print("Result",response.result) // result of response serialization
print("parameters = \(parameter)")
switch response.result
case .success(let value):
completionHandler(value as AnyObject, "No error found")
print("responseObject: \(value)")
case .failure(let responseError):
print("responseError: \(responseError)")
case .failure(let encodingError):
print("encodingError: \(encodingError)")
let errorDesc = (encodingError as NSError).localizedDescription
completionHandler(errorDesc as NSString,"Some error found")
)
我在这一行遇到一个错误
if let data = (value as AnyObject).data(using: String.Encoding.utf8.rawValue)
我认为它只需要字符串参数,但我同时拥有 String 和 NSNumber。所以这是我的问题,如何对值字符串和 NSNumber 进行编码。请有人帮助/建议我。
【问题讨论】:
您可以发布您尝试过的代码示例吗? 这可能会帮助你***.com/questions/49230181/… 对多个图像使用github.com/hyperoslo/ImagePicker,并将其作为字符串传递给参数 是的@DilipTiwari 我会检查 如果有任何帮助请求让我知道我已经在使用上面的链接并使用多个图像数组发送多个参数 【参考方案1】:使用此方法在服务器上上传图像数组。 (如果您的服务器接受它们)。
class func uploadImageCall(arrayOfImageToUpload:[UIImage])
Alamofire.upload(multipartFormData: (multipartFormData : MultipartFormData) in
let count = arrayOfImageToUpload.count
for i in 0..<count
multipartFormData.append(arrayOfImageToUpload[i], withName: "morephoto[\(i)]", fileName: "photo\(i).jpeg" , mimeType: "image/jpeg")
for (key, value) in parameterrs
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
print(multipartFormData)
, to: url!) (result) in
switch result
case .success(let upload, _ , _):
upload.uploadProgress(closure: (progress) in
print("uploding: \(progress.fractionCompleted)")
)
upload.responseJSON response in
print(response.result.value!)
case .failure(let encodingError):
print("failed")
print(encodingError)
使用 arrayOfImageToUpload 作为参数。并在要上传图片的类中调用此方法。
【讨论】:
谢谢@MRizwan33。为回答。如何发送其他参数..? 在添加另一个名为 arrayOfImageToUpload 的参数之前调用它。我已经编辑检查它。 嗨@MRizwan,我正在使用您建议的代码,但出现一个错误,如何解决此错误,“无法使用类型为'的参数列表调用'附加'(任何,withName:字符串,文件名:字符串,mimeType:字符串)'" 这意味着在 swift 4.0 及以上版本中追加的方法有一些变化,尝试找出更多方法来编写相同的方法。【参考方案2】:使用以下方法使用 Alamofire 发送多个具有不同参数的图像。
func uplaodImages(_ url: String,parameters: Dictionary<String,AnyObject>?,imageDataArray:[UIImage], compBlock : @escaping completionBlock,failure : @escaping failureBlock)
let headers: HTTPHeaders = [
/* "Authorization": "your_access_token", in case you need authorization header */
"Content-type": "multipart/form-data"
]
Alamofire.upload(multipartFormData: multipartFormData in
for (key, value) in parameters!
if let data = value.data(using: String.Encoding.utf8.rawValue)
multipartFormData.append(data, withName: key)
for i in 0..<imageDataArray.count
let imageData1 = UIImageJPEGRepresentation(imageDataArray[i], 1.0)!
multipartFormData.append(imageData1, withName: "morephoto[\(i)]" , fileName: "photo" + String(i) + ".jpg", mimeType: "image/jpeg")
,
to: url,method:HTTPMethod.post,
headers:headers, encodingCompletion: encodingResult in
switch encodingResult
case .success(let upload, _, _):
upload
.validate()
.responseJSON response in
switch response.result
case .success(let value):
compBlock(value as AnyObject,true)
print("responseObject: \(value)")
case .failure(let responseError):
print("responseError: \(responseError)")
case .failure(let encodingError):
print("encodingError: \(encodingError)")
let errorDesc = (encodingError as NSError).localizedDescription
failure(errorDesc as NSString,false)
)
【讨论】:
嗨@Daggarwal 谢谢你的回答,但我在这行“if let data = value.data(using: String.Encoding.utf8.rawValue)”中感到震惊,我收到了这个错误-“由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'-[__NSCFNumber dataUsingEncoding:]:无法识别的选择器发送到实例0x60c000637320'”【参考方案3】:func mulipartImageupload()
doOnMain
Loading.sharedInstance.startloading()
let url = NSURL(string:"\(Constant.BaseURL)")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
var headers = ["Content-Type":"application/x-www-form-urlencoded"]
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
if !GlobalClass.sharedInstance.getCustomerKey().isEmpty
headers = ["Accept-Language": "en",
"Authorization" : "Token"]
request.allHTTPHeaderFields = headers
let image_data = productImage.jpeg(.lowest)
if(image_data == nil)
return
let image_data1 = productImage1.jpeg(.lowest)
if(image_data1 == nil)
return
let body = NSMutableData()
let fname = "parameter1"
let fname1 = "parameter2"
let mimetype = "image/png"
let parameters = dict
if parameters != nil
for (key, value) in parameters
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
if isFrontImage == true
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"test\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("hi\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"parameter1\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(image_data!)
if isBackImage == true
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"test\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("hi\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"parameter2\"; filename=\"\(fname1)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(image_data1!)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest)
(
data, response, error) in
guard let _:NSData = data! as NSData, let _:URLResponse = response, error == nil else
print("error")
return
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("****** response data = \(responseString!)")
do
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
let dict = json?.value(forKey: "data") as? NSDictionary ?? [:]
print("****** response json = \(json!)")
if json?.value(forKeyPath: "status") as? Int == 200
let dict = json?.value(forKey: "data") as? NSDictionary ?? [:]
DispatchQueue.main.async
Loading.sharedInstance.stoploading()
else
Loading.sharedInstance.stoploading()
catch
print(error)
Loading.sharedInstance.stoploading()
task.resume()
func generateBoundaryString() -> String
return "Boundary-\(NSUUID().uuidString)"
extension UIImage
enum JPEGQuality: CGFloat
case lowest = 0
case low = 0.25
case medium = 0.5
case high = 0.75
case highest = 1
/// Returns the data for the specified image in JPEG format.
/// If the image object’s underlying image data has been purged, calling this function forces that data to be reloaded into memory.
/// - returns: A data object containing the JPEG data, or nil if there was a problem generating the data. This function may return nil if the image has no data or if the underlying CGImageRef contains data in an unsupported bitmap format.
func jpeg(_ jpegQuality: JPEGQuality) -> Data?
return jpegData(compressionQuality: jpegQuality.rawValue)
【讨论】:
以上是关于如何在 Swift 4 中使用 Alamofire 上传具有其他参数的多个图像的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 4 中使用 Alamofire 上传具有其他参数的多个图像
Alamofire 4 请求返回 NSArray,无法弄清楚如何在 Swift 3 中使用 SwiftyJSON 进行解析
如何使用 Alamofire Swift 4 在 JSON 编码中传递数据
如何使用 Alamofire,Swift 4 为 UICollectionView 获取 JSON 数据