3

How to upload MultipartFormData with authentication using Alamofire? The part that I don't understand is where to put .authenticate(user: username, password: password).? This is how I usually upload pictures using MultipartFormData:

Alamofire.upload(
        .POST, "https://myExampleUrl/photo/upload", headers: headers, multipartFormData: { multipartFormData in
            multipartFormData.appendBodyPart(data: "default".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, 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)
            }
        }
    )

I think it's possible to add authentication process into headers?

Xernox
  • 1,706
  • 1
  • 23
  • 37

2 Answers2

2

Haven't had much time to explore the API for rilbits.com. When I visited the address in Safari, I got the following error:

Please add 'Authorization' or 'X-Access-Token' header to your request 

This suggests 2 options for you:

  1. Login first and get back an access token, which you can then use the for the upload request
  2. Send a basic Authorization header along with the upload request.

Here's how you can send the Authorization header (second option):

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)
        }
    }
)

Full disclosure:

  • The authorization code was lifted from Alamofire's readme
  • I didn't test the code above
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • 2
    This is not work in swift 3.0. Any suggestion for swift 3.0 ? – Mitul Marsoniya Sep 19 '16 at 12:03
  • 2
    This no longer works in the latest version (4.0) of Alamofire. Because the header parameters in the upload function is no longer there. Any ideas please? – JayVDiyk Sep 22 '16 at 05:40
  • how about audio file in Alamofire 4? - i try to send a audio file in this form : multipartFormData.append(audioLocalPath, withName: "file", fileName: "file", mimeType: "application/octet-stream") but occur this error : multipartEncodingFailed(Alamofire.AFError.MultipartEncodingFailureReason.bodyPartFileNotReachableWithError(file:///var/mobile/Containers/....... /Documents/item.mp3, NSUnderlyingError=0x16049100 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}})) - where is problem? -bad request or bad audio path? – Saeid Dec 06 '16 at 13:52
  • @JayVDiyk At 4.4.0, it seems the parameter is back again. – Raphael Mar 07 '17 at 16:10
1

Alamofire.upload does not really upload here: it only writes the multi-part request into a file.

When you call .responseX on upload in encodingCompletion, that's when the request is actually performed. That is,

upload.authenticate(user: username, password: password)
      .responseString { ...}

should do what you want.

If you authenticate with headers, setting the headers parameter of Alamofire.upload should still work; as far as I can tell, it should forward the headers to upload. You can verify that by dumping upload to the console, and you can also set headers to upload as you would for normal requests.

Raphael
  • 9,779
  • 5
  • 63
  • 94