HttpBody request Swift



I'm actually trying to upload image to Imgur using its API.


I followed a tutorial and when it talks about the HttpBody tells to do something like

Code Block
request.addValue("multipart/form-data; boundary=&", forHTTPHeaderField: "Content-Type")
var body = ""
body += "--&\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "--&)--\r\n"
let postData = body.data(using: .utf8)
request.httpBody = postData

Which works perfectly fine but I don't understand how to add other
variables to the body which is why after browsing on different
StackOverflow questions I tried to do something on my own by setting the
boundary as '&' and then just tried to do the following:

Code Block
let bodyData = "image=\(base64Image ?? "")"
request.httpBody = bodyData.data(using: .utf8)


But I always end-up having server errors and I don't understand what I am doing wrong


Any help could be appreciated
Code Block
Answered by LucasFab in 641386022

You usually put Content-Disposition:form-data; name="field-name" as the part header for the text field.

I tried to do as instructed which makes my body looks like this:

Code Block
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "Content-Disposition:form-data; name=\"title\""
body += "\r\n\r\n\(name)\r\n"
body += "--\(boundary)--\r\n"


The request still works but the title of the picture is not defined

I think I did not mention it but the request I'm trying to use is the post image from the Imgur API

https://apidocs.imgur.com/#de179b6a-3eda-4406-a8d7-1fb06c17cb9c

Edit: Also tried adding a boundary between to have something like this:

Code Block
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "--\(boundary)--\r\n"
body += "Content-Disposition:form-data; name=\"title\""
body += "\r\n\r\n\(name)\r\n"
body += "--\(boundary)--\r\n"


but this is still not working

Edit2:

Had to change the way of putting the boundary to something like this:

Code Block
body += "--\(boundary)\r\n"


which makes the body look like this:
Code Block
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"title\""
body += "\r\n\r\n\(name)\r\n"
body += "--\(boundary)--\r\n"


Which is now working

Thanks again for your help and the time you took to answer my questions !







I tried to do something on my own by setting the boundary as '&'

I strongly recommend you not to use too short string such as "&" as boundary.

let bodyData = "image=\(base64Image ?? "")"

The bodyData is not in the right format for multipart/form-data.

I don't understand how to add other variables to the body

Can you explain the details about the other variables?
What I do usually is generate a unique boundary, such as:

Code Block
func generateBoundaryString() -> String {
            return "Boundary--\(UUID().uuidString)"
        }


and use in contentType

Code Block
            let boundaryString = generateBoundaryString()
            let contentType : String? = "multipart/form-data; boundary=\(boundaryString)"  


Do you setValue of the request before the code you show ?
Code Block
            request.setValue(contentType, forHTTPHeaderField: "Content-Type")

I noticed I had problems with addValue

I strongly recommend you not to use too short string such as "&" as boundary.

I chose to generate a UID as my boundary


The bodyData is not in the right format for multipart/form-data.


I've been looking at the format of the form-data and based on what I saw on the tutorial I now have:
Code Block
var body = ""
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "; name=\"title\""
body += "mycat\r\n"
body += "--\(boundary)--\r\n"
let postData = body.data(using: .utf8)
request.httpBody = postData


The request works perfectly fine, the response I get is the following:
Code Block
{"data":{"id":"wfoNb7C","title":null,"description":null,"datetime":1602920269,"type":"image\/png","animated":false,"width":275,"height":183,"size":90250,"views":0,"bandwidth":0,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":139373323,"is_ad":false,"in_most_viral":false,"has_sound":false,"tags":[],"ad_type":0,"ad_url":"","edited":"0","in_gallery":false,"deletehash":"fQm4439FpbjD3Ya","name":"","link":"https:\/\/i.imgur.com\/wfoNb7C.png"},"success":true,"status":200}

but the title of the image is not set despite I try to add it in my request

Any ideas on how to fix this problem ?

Any ideas on how to fix this problem ?

You usually put Content-Disposition:form-data; name="field-name" as the part header for the text field.

Have you tried using body += "Content-Disposition:form-data; name=\"title\"" instead of body += "; name=\"title\"" ?
Accepted Answer

You usually put Content-Disposition:form-data; name="field-name" as the part header for the text field.

I tried to do as instructed which makes my body looks like this:

Code Block
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "Content-Disposition:form-data; name=\"title\""
body += "\r\n\r\n\(name)\r\n"
body += "--\(boundary)--\r\n"


The request still works but the title of the picture is not defined

I think I did not mention it but the request I'm trying to use is the post image from the Imgur API

https://apidocs.imgur.com/#de179b6a-3eda-4406-a8d7-1fb06c17cb9c

Edit: Also tried adding a boundary between to have something like this:

Code Block
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "--\(boundary)--\r\n"
body += "Content-Disposition:form-data; name=\"title\""
body += "\r\n\r\n\(name)\r\n"
body += "--\(boundary)--\r\n"


but this is still not working

Edit2:

Had to change the way of putting the boundary to something like this:

Code Block
body += "--\(boundary)\r\n"


which makes the body look like this:
Code Block
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"image\""
body += "\r\n\r\n\(base64Image ?? "")\r\n"
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"title\""
body += "\r\n\r\n\(name)\r\n"
body += "--\(boundary)--\r\n"


Which is now working

Thanks again for your help and the time you took to answer my questions !







HttpBody request Swift
 
 
Q