1

I'm using Alamofire 5, and I'm trying to upload an image to a Rocket Chat server. The corresponding curl statement that I need to duplicate using AF is at the following link: (link to documentation: https://docs.rocket.chat/api/rest-api/methods/rooms/upload)

I've been trying to upload using multipartFormData with no success. I've also attempted to bypass Alamofire altogether and use Swift URLSession. The best I can do is get the same error message from the server, which is "errorType": invalid-field."

My code as it stands right now:

let url = URL_MESSAGES + "rooms.upload/\(_group._id ?? "")"
    
let boundary = UUID().uuidString

let headers: HTTPHeaders = [
    
"X-Auth-Token": authToken,
    "X-User-Id": me._id ?? "",
    "Content-type":"multipart/form-data; boundary=\(boundary)"
]

if let data = image.jpeg(.medium) {
        
    print(data.count)
        
    AF.upload(
        multipartFormData: { multipartFormData in
                multipartFormData.append(data, withName: "image", fileName: "image.jpeg", mimeType: "image/jpeg")
        },
            to: url, method: .post , headers: header)
            .response { resp in
                print(resp)

        }
        .cURLDescription { description in
            print(description)
        }
        .responseString { [weak self] (response) in
            
            DispatchQueue.main.async {                 
                if response.error == nil {
                    
                    guard let data = response.data else {
                        return completion(true,[:])
                    }

                    if let json = try? JSON(data: data) {

                        let dictionaryIn = json.rawValue as! [String : Any]

                        if (self?.isSuccess(data: dictionaryIn))! {
                            completion(true,json.rawValue as! [String : Any])
                        }else{
                            completion(false,[:])
                            self?.handleError(data: dictionaryIn)
                        }
                    }

                }else{
                        completion(false,[:])
                        self?.handleError(data: [:])
                }
            }
        }
    }
}
andrewlewisdev
  • 202
  • 2
  • 11

2 Answers2

0

I think you're breaking the upload by trying to set your own boundary. Alamofire will that for you automatically. Try removing the header.

Jon Shier
  • 12,200
  • 3
  • 35
  • 37
0

The above code works perfectly, when I changed this:

 AF.upload(
    multipartFormData: { multipartFormData in
            multipartFormData.append(data, withName: "image", fileName: "image.jpeg", mimeType: "image/jpeg")

to:

 AF.upload(
    multipartFormData: { multipartFormData in
            multipartFormData.append(data, withName: "file", fileName: "image.jpeg", mimeType: "image/jpeg")

Swapping out "image" for "file" fixed everything. I went with "image" because this is what every Alamofire tutorial I could find said to do. However, RocketChat requires it to be "file". It is in the documentation, but I didn't realize that's what it was telling me to do. Specifically, in the documentation, it says:

"Note: For some file types if uploading via curl you may need to set the mime type. With some file types, curl will upload the file as application/octet-stream. You can pass a custom mime type like this: -F "file=@file.wav;type=audio/wav" "

I was trying -F "image=@file.wav;type=audio/wav" when translated from Alamofire. It needs to be: -F "file=@file.wav;type=audio/wav"

andrewlewisdev
  • 202
  • 2
  • 11