21

I am developing an iPhone application with swift. and I'am using Alamofire framework for handling http requests. I use Alamofire.request for POST , GET and etc like this:

Alamofire.request(.POST, myURL , parameters: ["a": "1", "b" : "2" ]) .response { (request, response, data, error) in } 

And I use Alamofire.upload to upload image to server this :

Alamofire.upload(.POST, uploadURL , fileURL) 

And both works perfectly, but now I want to upload an image and also send some parameters with, and my content type should be multipart/form-data and Alamofire.upload does not accept parameters.

There are two more question on SO about this issue with swift, which first one is not using Alamofire (and really, why not?) and in second one, mattt (Alamofire Developer) cited to use encoding parameters.

I checked his example, but still couldn't figure out how to do that.

Can any one please help me solve this problem?

Thank you! :)

4
  • Here's the solution I found, posted to another question: stackoverflow.com/questions/26121827/… Commented Nov 5, 2014 at 0:46
  • Reza_Rg Can you please help me? I also use 'Alamofire.upload(.POST, uploadURL , fileURL)', but how do I have to structure the php file to receive the file? Where is the file sent via .POST available in my php file? Commented Jun 3, 2015 at 16:27
  • @Reza_Rg did you solve your problem, if so can you share an answer? Commented Jun 16, 2015 at 13:40
  • @user2363025 Yes, but I ended up changing some codes on Alamofire library, which I know is not the right thing to do. Commented Jun 17, 2015 at 5:56

6 Answers 6

25

you can use Alamofire 3.0+ below code

func uploadImageAndData(){ //parameters let gender = "M" let firstName = "firstName" let lastName = "lastName" let dob = "11-Jan-2000" let aboutme = "aboutme" let token = "token" var parameters = [String:AnyObject]() parameters = ["gender":gender, "firstName":firstName, "dob":dob, "aboutme":about, "token":token, "lastName":lastName] let URL = "http://yourserviceurl/" let image = UIImage(named: "image.png") Alamofire.upload(.POST, URL, multipartFormData: { multipartFormData in if let imageData = UIImageJPEGRepresentation(image, 0.6) { multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "file.png", mimeType: "image/png") } for (key, value) in parameters { multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key) } }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): print("s") upload.responseJSON { response in print(response.request) // original URL request print(response.response) // URL response print(response.data) // server data print(response.result) // result of response serialization if let JSON = response.result.value { print("JSON: \(JSON)") } } case .Failure(let encodingError): print(encodingError) } }) } 
Sign up to request clarification or add additional context in comments.

6 Comments

HTTP Error 415 Unsupported media type plz check image type @chamathjeevan
If there is a key "image" in following parameter ["gender":gender,"firstName":firstName,"dob":dob,"aboutme":aboutme,"token":token,"lastName":lastName, "image": imageData] then multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "file.png", mimeType: "image/png") will append in parameters?
@amitgupta I hope you got my question above
Works great, one question If I take a picture from camera and perfrom UIImagePNGRepresentation function on UIImage, how do I preserve the orientation?
It is not working for swift 3 even when changed the syntax a/c to swift 3
|
4

SWIFT 2 AlamoFire Simple Image Upload (REST API)

@amit gupta It seems answer contains big overhead. AlamoFire contain load of simplified solution. Alamofire.request method contains several simplified overload which can use to upload in simple manner. By using Alamofire.request( method developer can get rid of encoding overhead.

HTTP Status 415 gives because of not specifying the correct media type.

Please check my solution below.

import UIKit import Alamofire class ViewController: UIViewController { @IBOutlet var imageView: UIImageView! @IBOutlet var btnUpload: UIButton! override func viewDidLoad() { super.viewDidLoad() } func successDataHandler(responseData:String){ print ("IMAGE UPLOAD SUCCESSFUL !!!") } func failureDataHandler(errorData:String){ print (" !!! IMAGE UPLOAD FAILURE !!! ") } @IBAction func actionUpload(sender: AnyObject) { let URL = "http://m8coreapibeta.azurewebsites.net/api/cards/SaveImages" let postDataProlife:[String:AnyObject] = ["CardId":(dataCardDetail?.userId)!,"ImageType":1,"ImageData":imageView.image!] uplaodImageData(URL, postData: postDataProlife, successHandler: successDataHandler, failureHandler: failureDataHandler) } func uplaodImageData(RequestURL: String,postData:[String:AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () { let headerData:[String : String] = ["Content-Type":"application/json"] Alamofire.request(.POST,RequestURL, parameters: postData, encoding: .URLEncodedInURL, headers: headerData).responseString{ response in switch response.result { case .Success: print(response.response?.statusCode) successHandler(response.result.value!) case .Failure(let error): failureHandler("\(error)") } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } 

Comments

3

Almaofire with swift 3.0

Alamofire.upload(multipartFormData: { multipartFormData in var index = 1 for image in imageArray { let imageData: Data = (UIImageJPEGRepresentation(image, 1.0) as Data?)! multipartFormData.append(imageData, withName: "home-\(index)", fileName: "home-\(index)", mimeType: "image/jpeg") index += 1 } }, with: requestName, encodingCompletion: { result in switch result { case .success(let upload, _, _): upload.responseJSON { response in print("Image(s) Uploaded successfully:\(response)") } case .failure(let encodingError): print("encodingError:\(encodingError)") } }) 

1 Comment

my problem is images names and directories how to achieve images in the gallery directories and their names?
3

Swift 4 with Alamofire 4

let isConnected = connectivity.isConnectedToInternet() func updateProfile(firstName:String,lastName:String ,imageData:Data?,completion: @escaping (isValidUser)->()) { if self.isConnected { var parameters : [String:String] = [:] parameters["auth_key"] = loginUser?.authKey! parameters["first_name"] = firstName parameters["last_name"] = lastName let url = "\(baseUrl)\(basicAuthenticationUrl.updateProfile)" print(url) 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: "image_url", fileName: "image.png", mimeType: "image/png") } }, 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)") } } } } 

Comments

0

Almaofire with swift 2.0 just copy and paste below code.here m asumming JSON response from server

 func uploadImageRemote (imageData : NSData?) -> Dictionary <String,AnyObject>{ var imageDictionary = Dictionary<String,AnyObject>() var tokenHeaders:[String:String]! = ["x-access-token":Constants.kUserDefaults.stringForKey("userToken")!] Alamofire.upload( .POST, "http://52.26.230.146:3300/api/profiles/imageUpload",headers:tokenHeaders, multipartFormData: { multipartFormData in multipartFormData.appendBodyPart(data: imageData!, name: "upload", fileName: "imageFileName.jpg", mimeType: "image/jpeg") }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in print("Uploading Avatar \(totalBytesWritten) / \(totalBytesExpectedToWrite)") dispatch_async(dispatch_get_main_queue(),{ }) } upload.responseJSON { response in guard response.result.error == nil else { print("error calling GET \(response.result.error!)") return } if let value = response.result.value { print("Success JSON is:\(value)") if let result = value as? Dictionary<String, AnyObject> { imageDictionary["imageUrl"] = result["url"] } } dispatch_async(dispatch_get_main_queue(),{ //Show Alert in UI print("Avatar uploaded"); }) } case .Failure(let encodingError): //Show Alert in UI print("Avatar not uploaded \(encodingError)"); } } ); return imageDictionary } 

Comments

-2

To use encoding Parameters, make a ParameterEncoding variable, assign it a encoding type (case of the enum which include .JSON, .URL) and then use the encode function with your NSURLRequest and the parameters. This function returns a tuple of two element, the first being the resulting NSURLRequest and the second being the resulting possible NSError.

Here's how I used it for a custom header I needed in a project

 var parameterEncoding:ParameterEncoding! switch method { case .POST, .PUT : parameterEncoding = ParameterEncoding.JSON default : parameterEncoding = ParameterEncoding.URL } var alamoRequest = Alamofire.Manager.sharedInstance.request(parameterEncoding.encode(mutableURLRequest, parameters: parameters).0) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.