0

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

Libor Zapletal
  • 13,752
  • 20
  • 95
  • 182
  • https://stackoverflow.com/a/38798445/1271826 outlines a number of options, namely `application/x-www-form-urlencoded` (simpler), `multipart-formdata` (more convoluted, needed only if you are including binary payloads) as well as the third-party library, Alamofire, which simplifies both of these. – Rob Sep 19 '22 at 06:22
  • FWIW, see https://stackoverflow.com/a/26365148/1271826 for example of `application/x-www-form-urlencoded` request. – Rob Sep 19 '22 at 06:33

1 Answers1

0

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.

dgatwood
  • 10,129
  • 1
  • 28
  • 49