Upload files using multipart request - Swift 4 - ios

I have to upload files on server using multipart request. For network calls i am using Alamofire.
What i have done so far is below
Request Service:
Multipart request:-
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
let fileData = Filedata() // getting data from local path
let URL = try! URLRequest(url: "https://SomeUrl/upload", method: .post, headers: headers)
Alamofire.upload(multipartFormData: { (multipartFormData) in
//multipartFormData.append(fileData, withName: "image", fileName: "image", mimeType: "image/png")
multipartFormData.append(fileData, withName: "file")
}, with: URL, encodingCompletion: { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response)
}
case .failure(let encodingError):
print(encodingError)
}
})
Response:-
{ Status Code: 400, Headers {
Connection = (
close
);
"Content-Type" = (
"application/json;charset=UTF-8"
);
Date = (
"Tue, 15 May 2018 10:34:15 GMT"
);
"Transfer-Encoding" = (
Identity
);
} }
[Data]: 171 bytes
[Result]: SUCCESS: {
error = "Bad Request";
message = "Required request part 'file' is not present";
path = "/files/safebolt.org/upload";
status = 400;
timestamp = "2018-05-15T10:34:15.715+0000";
}
Can anyone please tell me what i am doing wrong with request ?

Try with:
multipartFormData.append(fileData, withName: "file", fileName: "file", mimeType: "image/png")

I have created one function. Hope it works for you.
//Alamofire file upload code
func requestWith(URLString: String,
imageData: Data?,
fileName: String?,
pathExtension: String?,
parameters: [String : Any],
onView: UIView?,
vc: UIViewController,
completion:#escaping (Any?) -> Void,
failure: #escaping (Error?) -> Void) {
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
let URL = BASE_PATH + URLString
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
if let data = imageData {
multipartFormData.append(data, withName: "fileUpload", fileName: "\(fileName!).\(pathExtension!)", mimeType: "\(fileName!)/\(pathExtension!)")
}
}, usingThreshold: UInt64.init(), to: URL, method: .post, headers: headers) { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
if let err = response.error {
failure(err)
return
}
completion(response.result.value)
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
failure(error)
}
}
}

Try This, is an example it works for me. If you want to convert encode 64 for images add extension. If simply post the data and image this code may help.
//creating parameters for the post request
let parameters: Parameters=[
"ad_title":classText1.text!,
"ad_description":classText2.text!,
"ad_category":CategoryClass.text!,
"ad_condition":classText3.text!,
"ad_username":classText6.text!,
"ad_usermobile":classText7.text!,
"ad_city":classText8.text!,
"ad_price":classText4.text!,
"negotiable":classText5.text!,
"image1":adImage1.image!,
"image2":adImage2.image!,
"image3":adImage3.image!,
"image4":adImage4.image!
]
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
}, usingThreshold: UInt64.init(), to: URL, method: .post) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
print("Succesfully uploaded = \(response)")
if let err = response.error{
print(err)
return
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
}
}

Related

I want to upload image to multipart form data using alamofire swift 5

I want to upload png image to URL like postman , i used postman
postman screenshot
I used this function to upload png image to url using post method using Alamofire
this is upload function , but it return error code 500 Internal server error although it success with code 200 in postman
static func updateProfileImage(image : UIImage , result : #escaping()->()) {
if let user = UserDefaults.standard.string(forKey: "mail") , let imgData = image.pngData(){
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append("form-data".data(using: .utf8 ,allowLossyConversion: false)!, withName: "Content-Disposition")
//multipartFormData.append("name".data(using: .utf8 ,allowLossyConversion: false)!, withName: "fileUpload")
multipartFormData.append(imgData, withName: "fileUpload", mimeType: "image/png")
},
to: URLs.profileImage+user,method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { response in
print(response)
}
case .failure( _):
print("error")
}
}
)
}
I have code of multipart data request follows, I hope this will help you.
Alamofire.upload( multipartFormData: { multipartFormData in
// parameters is method arguments in my webs ervice call method
for (key, value) in parameters {
if let data = (value as! String).data(using: .utf8) {
multipartFormData.append(data, withName: key)
}
}
let imageData = image?.jpegData(compressionQuality: 0.5)
multipartFormData.append(imageData!, withName: "profile_image", fileName: "profileImage", mimeType: "image/jpeg")
// getURL(.addProfile) will create url, method from my structure
// getHeaders() will return required header from that method
}, to: getURL(.addProfile), headers: getHeaders(), encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response(completionHandler: { (defaultDataResponse) in
guard let httpResponse = defaultDataResponse.response else {
completion(nil, defaultDataResponse.error)
return
}
if httpResponse.statusCode == 200 {
// Success Code
} else {
// Failed code
}
})
case .failure(let encodingError):
// Failed code.
}
})
Try this
func generateBoundary() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
//Set Headers with required auth
let boundary = generateBoundary()
let headers = ["content-type": "multipart/form-data; boundary=\(boundary)",
"Content-Type": "application/json",
"cache-control": "no-cache"]
//Api Call
Alamofire.upload(multipartFormData:{ multipartFormData in
if let image = imageData {
multipartFormData.append(image, withName: "<param_key>", fileName: objIdentityDetails.fileName ?? (String(Date().timeIntervalSince1970) + ".jpeg"), mimeType: "image/jpeg")
}
for (key, value) in parameters {
multipartFormData.append(value?.data(using: String.Encoding.utf8) ?? Data(), withName: key)
}},
usingThreshold:UInt64.init(),
to: try! <URL>,
method: .post,
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseObject { (response: <model>) in
switch response.result {
case .failure (let error):
//Error
case .success (let responseObject):
//response
}
}
case .failure(let encodingError):
//Error
}
})
You can use this following code to upload :
Alamofire.upload(multipartFormData:{ multipartFormData in multipartFormData.append(img, withName: "image", fileName: "image.png", mimeType: "image/png") },
"img" - Is Your Image Data &
"withName" - Is Your Name In Postman &
"fileName" - Your Image Name Which You Want To Upload

File upload issue in ios

I have a problem uploading a Document file through Document picker controller. I have selected File through Document picker. and send file using multipart data in service. but xcode give some error in ios swift.
Here is my code For Image upload.
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in params {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
multipartFormData.append(imageData!, withName: "upload_photo", fileName: "img.png", mimeType: "image/jpeg")
}, to:pageURL)
{ (result) in
switch result {
case .success(let upload, _, _):
self.stopLoader()
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
But i have to upload Document file from url.
Use my below class it is simple and manageable and working file :
import UIKit
import Alamofire
class TDWebServices: NSObject {
static let shared = TDWebServices()
func post(urlString : String , param : [String : Any], completionHandler : #escaping ( _ result : Any?) -> ()) {
Alamofire.request(urlString, method: .post, parameters: param, encoding: JSONEncoding.default, headers: ["Accept": "application/json"]).responseJSON { (response) in
switch response.result {
case .success:
let json = response.result.value as? NSDictionary
completionHandler(json)
case .failure(let error):
print(error)
completionHandler(nil)
return
}
}
}
func uploadImage(urlString : String , image : UIImage, param : [String : Any], completionHandler : #escaping ( _ result : Any?) -> ()) {
guard let imageData = UIImageJPEGRepresentation(image, 0.5) else {
print("Could not get JPEG representation of UIImage")
return
}
let header: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in param {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
multipartFormData.append(imageData,
withName: "image", // <- It is param for uploading the file make sure it is perfect as per your API
fileName: "image.jpg",
mimeType: "image/jpeg")
},
to: urlString,
headers: header, // ["Authorization": "Basic xxx"]
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress { progress in
// progressCompletion(Float(progress.fractionCompleted))
}
upload.validate()
upload.responseJSON { response in
completionHandler(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
completionHandler(nil)
}
})
}
}
How to use?
let param = ["user_id" : 123 as Any] // Whatever your params are
// showActivity() // <- show activity indicator
TDWebServices.shared.post(urlString: <your_api_url>, param: param) { (res) in
// hideActivity() // <- hide activity indicator
if res != nil{
let aDict = res as? [String : Any] // your response
// Hnadle your code here
}
else{
self.showAlert(title: "Invalid!", message: "Internet connection issue.", calcelHandler: {}) // <- If you have internet issue
}
}
Still facing issue then let me know..

How to upload an image using alamofire multipart form data with basic authentication?

I am new in programming and in iOS development. I need to upload an image using Alamofire multipart form data, but I also need to input basic authentication header.
in this thread Alamofire 4.0 Upload MultipartFormData Header, it seems similar to my problem, the code is like this to upload
Alamofire.upload(multipartFormData:{ multipartFormData in
multipartFormData.append(unicornImageURL, withName: "unicorn")
multipartFormData.append(rainbowImageURL, withName: "rainbow")},
usingThreshold:UInt64.init(),
to:"https://httpbin.org/post",
method:.post,
headers:["Authorization": "auth_token"],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
})
but I am confused how to put the basic authentication (i.e username & password) header. and I also confused where I should place my image data.
I find another thread that seems similar to my problem. here it is... How to upload MultipartFormData with authentication using Alamofire, the proposed solution is this code :
let username = "username"
let password = "password"
let credentialData = "\(username):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
let base64Credentials = credentialData.base64EncodedStringWithOptions([])
let headers = ["Authorization": base64Credentials]
Alamofire.upload(
.POST,
"https://rilbits.com/supersafe/photo/upload",
headers: headers,
multipartFormData: { multipartFormData in
let data = "default".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
multipartFormData.appendBodyPart(data: data, name: "_formname")
multipartFormData.appendBodyPart(fileURL: fileURL, name: "photo")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseString { response in
debugPrint(response)
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
but after fixing to the swift 4.1 it gives an error :
could you please help my problem? Thanks in advance :)
I have created this function: Hope it works for you:-
//Alamofire file upload code
func requestWith(URLString: String,
imageData: Data?,
fileName: String?,
pathExtension: String?,
parameters: [String : Any],
onView: UIView?,
vc: UIViewController,
completion:#escaping (Any?) -> Void,
failure: #escaping (Error?) -> Void) {
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
let URL = BASE_PATH + URLString
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
if let data = imageData {
multipartFormData.append(data, withName: "fileUpload", fileName: "\(fileName!).\(pathExtension!)", mimeType: "\(fileName!)/\(pathExtension!)")
}
}, usingThreshold: UInt64.init(), to: URL, method: .post, headers: headers) { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
if let err = response.error {
failure(err)
return
}
completion(response.result.value)
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
failure(error)
}
}
}
i finally found the answer, kindly please use my code below
func uploadDefect(defectRemark: String, defectLocation: String, defectImage: UIImage, fileNameImage: String, completion: #escaping(_ errorMessage: String?) -> Void) {
guard let imgData = defectImage.jpeg(.medium) else {return}
let urlUpload = URLService.uploadDefect.endPoint
let username = "admin"
let password = "1234"
let parameters : [String:Any] = ["defect_remark" : defectRemark, "defect_location": defectLocation, "tenant_id" : tenantID]
var headers: HTTPHeaders = [:]
if let authorizationHeader = Request.authorizationHeader(user: username, password: password) {
headers[authorizationHeader.key] = authorizationHeader.value
}
Alamofire.upload(
multipartFormData: { multipartFormData in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
multipartFormData.append(imgData, withName: "file", fileName: fileNameImage, mimeType: "image/jpeg")
},
to: urlUpload,
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
Use :
Alamofire.upload(multipartFormData:{ multipartFormData in
multipartFormData.append(data, withName: "_formname")
multipartFormData.append(fileURL, withName: "photo")},
usingThreshold:UInt64.init(),
to:"URL",
method:.post,
headers:["Authorization": "auth_token"],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
})

Upload image from gallery with parameters and header using Alamofire

I am trying to upload image but need to pass parameters and header as well, got help from google about parameters but not getting how to pass header also. Passing on the code below please guide.
Below is my code:
if (request.requestType == "Multipart")
{
var strToken : String = ""
if let access_token = UserDefaults.standard.string(forKey: "auth_token"){
let tokenValue = String(format: "Token %#", access_token);
strToken = tokenValue
}
let headers: HTTPHeaders = [
"Authorization": strToken,
"Content-Type": "multipart/form-data"
]
let img = request.image
let imgData = UIImageJPEGRepresentation(img, 0.2)!
do{
let strURL = try strCompleteURL.asURL()
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "image_path",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
},
to:strURL)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
if response.result.isSuccess {
print(response.result.value as Any)
if let data = response.data{
self.response.responseCode = response.response?.statusCode
self.processResult(data);
}
}
}
case .failure(let encodingError):
print(encodingError)
}
}
}
catch{
}
above code tries to upload image but not succeed because of missing header, please guide how to pass header and parameters as well.
Thanks
Hi I have used headers like this
func uploadImage( image:UIImage, url:String, _ successBlock:#escaping ( _ response: JSON )->Void , errorBlock: #escaping (_ error: NSError) -> Void ){
let path = baseUrl + url
print(path)
let headers = ["authorization": AppData().token]
let imgData = UIImageJPEGRepresentation(image, 0.2)!
let URL = try! URLRequest(url: path, method: .post, headers: headers)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imgData, withName: "image",fileName: "file.jpg", mimeType: "file")
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, with: URL) { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value)
if let value = response.result.value {
let json = JSON(value)
successBlock(json)
}
}
case .failure(let encodingError):
print(encodingError)
errorBlock(encodingError as NSError)
}
}
}
The Alamofire .upload() function has more parameters available than what you used. (This can be seen in the Alamofire.swift file in their pod folder)
public func upload(
multipartFormData: #escaping (MultipartFormData) -> Void,
usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
to url: URLConvertible,
method: HTTPMethod = .post,
headers: HTTPHeaders? = nil,
encodingCompletion: ((SessionManager.MultipartFormDataEncodingResult) -> Void)?)
{
return ...
}
In there you can see there is a parameter for headers that you have not made use of.
Without running the code myself and checking everything, this would be my best assumption of where your headers would go

Upload an image (Base64) using Alamofire Swift 3

Iam trying to upload 2 images to server with JSON request using alamofire
and here's my code :
let parameters = ["CreditCardImage":CreditCardImage,"CreditCardBackImage":CreditCardBackImage , "CustomerID" : CustomerID]
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
Alamofire.request("MY URL", method : .post , parameters : parameters, encoding: JSONEncoding.default , headers: headers).responseJSON { response in
// get json Response
let json = JSON(response.result.value)
print(json)
}
When i print the response iam getting message << unknown >> in the console
and i tried that in postman it's not working too what's wrong with that ? any help ?
you should use other Alamofire methods. Here is an example:
func uploadAvatar(image: UIImage) {
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")
}
}, to: self.serverAddress + "/user/uploadAvatar", method: .post, headers: ["Authorization": User.shared.token], encodingCompletion: { _ in })
}
You can try this
let image = UIImage.init(named: "myImage")
let imgData = UIImageJPEGRepresentation(image!, 0.2)!
let parameters = ["name": rname]
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "fileset",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
},
to:"mysite/upload.php")
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
}
}

Resources