2

So I'm trying to do an async POST request to my server from my iOS device.

Here's the Swift code I've written:

    var urlString = "https://eamorr.com/ajax/login.php"
    var url = NSURL(string: urlString)
    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    var params = ["uname":"Eamorr", "pword":"mySecret"] as Dictionary<String, String>
    request.HTTPBody = params.   //what to do here???
    var connection = NSURLConnection(request: request, delegate: self, startImmediately: true)

The problem is, how do (reliably) convert the params to a POST string? (My server is expecting plain old POST parameters... Nothing fancy - no JSON, etc.)

I need this to be very reliable (i.e. not a hack), so I'd prefer if there was some base class (written by Apple) that I could use.

Does anyone have any ideas?

Eamorr
  • 9,872
  • 34
  • 125
  • 209
  • Writing your own solution isn't a hack, and is easy if the keys and values are always strings – Wain Feb 09 '15 at 12:39
  • possible duplicate of [Creating URL query parameters from NSDictionary objects in ObjectiveC](http://stackoverflow.com/questions/718429/creating-url-query-parameters-from-nsdictionary-objects-in-objectivec) – Bill Feb 09 '15 at 12:42

2 Answers2

2

Some of what bbarnhart suggests, but to actually create the body data, use:

let body = "&".join(map(params, {
    let key = $0.0.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
    let value = $0.1.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
    return "\(key!)=\(value!)"
}))
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)

Basically escape and convert each item into "key=value" and then string them all together separated by "&"

You'll also (probably) need to set the Content-Type header as recommended by bbarnhart:

request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
David Berry
  • 40,941
  • 12
  • 84
  • 95
1

To configure your post you need to do three things.

Set Content-Type to application/x-www-form-urlencoded

request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

Set the body as a key/value delimited by ampersand string and convert to NSData:

let myPostBody = "uname=Eamorr&pword=mySecret"
request.HTTPBoddy = (myPostBody as NSString).dataUsingEncoding(NSUTF8StringEncoding)

Set the Content-Length:

request.addValue(String(myPostBody.length), forHTTPHeaderField: "Content-Length")
bbarnhart
  • 6,620
  • 1
  • 40
  • 60
  • It seems too verbose. Some POST requests may have 10 parameters - ensuring the string is correct is time-consuming and unnecessary. – Eamorr Feb 09 '15 at 13:42
  • This answer does not fit the question. The paramater to convert to a httpbody is a dictionary not a string – thibaut noah May 15 '19 at 09:20
  • @thibautnoah HTTPBody has a type NSData. The questioner wants to send data back as a string but not a json formatted string. Form encoded uses a key=value&key=value&etc format. Let me know if I am still missing something. – bbarnhart May 15 '19 at 11:41
  • @bbarnhart it does not. httpBody is of type Data which is optional. I know the answer to the question, i am just saying you're not answering it as the questioner wanted to convert a dictionary. – thibaut noah May 15 '19 at 11:56