[SOLVED] URLSessionDataTask – upload parameters with multipart/form-data content type

Issue

This Content is from Stack Overflow. Question asked by Libor Zapletal

I would like to create body like in this curl example:

curl --location --request POST 'https://request.url' 
--header 'Authorization: Bearer xxx' 
--form 'name="Name"' 
--form 'data="[{"text": "This is comment", "another": "Thomas"}]"'

How can I implement this and correctly set httpBody in URLRequest?

I tried different approaches but nothing seems to work. Simple:

let body = NSMutableData()
body.appendString("name=" request.name))
body.appendString("data=" + "[{"text": "This is comment", "another": "Thomas" }]"))
return Data(body)

Then I tried to prepand: "Content-Disposition: form-data;". Or added line breakers. Nothing seems to be working.

That lines of code are part of class that helps me work with requests. What’s the simplest way to get it working? Thanks for help



Solution

The body is the body. The headers are the headers. It isn’t parsed. It is sent out as-is.

To add a header, you would create an NSMutableURLRequest (or I guess in Swift, it’s MutableURLRequest) and use the -setValue:forHTTPHeaderField: method or whatever the Swift equivalent name is.

For the specific request, assuming curl isn’t adding anything extra that is meaningful, the Objective-C code for that would be:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://request.url"]];
request.HTTPMethod = @"POST";

// This next bit may not work.  See explanation below.
request.setValue:@"Bearer xxx" forHTTPHeaderField:@"Authorization"];

request.setValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];
request.body = @"---------ThisIsABoundaryMarker\r\n"
                "Content-Disposition: form-data; name=\"Name\"\r\n"
                "\r\n"
                "[{\"text\": \"This is comment\", \"another\": \"Thomas\"}]\r\n"
                "---------ThisIsABoundaryMarker--\r\n";

And then just send that like you would any other NSURLRequest.

I’m not exactly sure how each of the method names translates to Swift but that should be pretty close to exactly correct, though form encoding is ugly, so YMMV. 🙂

There is a caveat, however. Overriding the Authorization field is explicitly forbidden in the docs, because in many cases, that will get stomped on. In your case, you’re not using anything that looks like password-based auth or public key auth, so AFAIK it shouldn’t, but I thought it was worth mentioning it in case you notice that part of the documentation later and freak out.

Of course, if macOS ever supports that authentication scheme natively, it absolutely could break (likely in a built-on-or-after fashion based on what SDK you link to, or one would hope). Keep that in mind. It’s probably safer if you can convince the server admins to let you pass a different header, like X-Authorization, and rewrite the header with a rewriting rule on the server side.


This Question was asked in StackOverflow by Libor Zapletal and Answered by dgatwood It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?