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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.