32

Here some code:

var URL: NSURL = NSURL(string: "http://stackoverflow.com")
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
request.HTTPBody = ?????? 
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) 
{
    (response, data, error) in
    println(NSString(data: data, encoding: NSUTF8StringEncoding))
}

What should I write in request.HTTPBody if I want send POST query "key" = "value" ?

Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
Max
  • 1,341
  • 3
  • 20
  • 39
  • what about https://stackoverflow.com/questions/24068866/perform-post-request-in-swift?rq=1 ? – AndrewShmig Jul 12 '14 at 15:49
  • I've seen this. But I did not see there example with key=value. Just "some data". For php it looks like: $_POST['key'] = "value"; – Max Jul 12 '14 at 15:52
  • 2
    As long as you are writing in Swift (which is iOS 7+) you might also consider using NSURLSession (also iOS 7+) rather than NSURLConnection. – phoebus Jul 12 '14 at 20:04
  • Please can you tell why NSURLSession is preferred than NSURLConnection? – Max Jul 12 '14 at 21:41
  • Guys sorry but can anyone tell me what does this line means (response, data, error) in println(NSString(data: data, encoding: NSUTF8StringEncoding)) – Keyur Padalia Oct 17 '14 at 12:59
  • using https://github.com/Alamofire/Alamofire is easier for these kind of work. thanks – Tareq Jobayere Mar 19 '15 at 22:39

4 Answers4

56

No different than in Objective-C, HTTPBody expects an NSData object:

var bodyData = "key1=value&key2=value&key3=value"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);

You'll have to setup the values & keys yourself in the string.

Fabián Heredia Montiel
  • 1,687
  • 1
  • 16
  • 30
pixel
  • 5,298
  • 8
  • 35
  • 32
  • I think I do something wrong: on the server I have just index.php: if($_POST['test'] == "some") echo "Works"; else echo "Not works". In additional of my code in first post I've added as you wrote: var bodyData = "some=test". And I've got "Not works". Something wrong with swift code? – Max Jul 12 '14 at 16:07
  • 1
    In the client you should be setting key=value, so the string should be test=some not some=test – pixel Jul 12 '14 at 17:27
  • It sounds strange, but problem was in URL address. I have index.php in folder /someFolder/ and URL was: "http://localhost/somefolder". When I changed it to "http://localhost/somefolder/". It works. But with first URL I've too got answer just not correct. So strange. – Max Jul 12 '14 at 21:41
  • how can I send through a base64 image? It is a long string and is cutting it off when sending to the server even though I am using post? –  Oct 08 '14 at 18:53
  • 1
    This doesn't property encode the data (escape/quote special chars and such). – ivan_pozdeev Oct 25 '15 at 01:55
  • How can I do that if I send parameters as dictionary – G.Abhisek Jan 25 '16 at 09:42
  • What if I want to let the user type an email for example and take that email and post it to check wether the email is already in the PHP script or not ? how can I do that – Hussein Reda AlBehary Dec 06 '16 at 11:04
  • Foretelling escaping headaches, I feel more comfortable with [this other answer using NSURLComponents](http://stackoverflow.com/a/34135087/871134) – Deleplace Feb 25 '17 at 22:00
2
class func postMethod (params: [String : AnyObject], apikey: String, completion: @escaping (Any) -> Void, failure:@escaping (Error) -> Void)
{
    if Utils().isConnectedToNetwork() == false
    {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
            Utils().HideLoader()
        })
        return
    }

    let strURL = Constants.BASE_URL + apikey
    let url = URL(string: strURL)
    print(params)
    print(strURL)

    var token = String()

    if((Constants.USERDEFAULTS .value(forKey: "token")) != nil){

        token = Constants.USERDEFAULTS.value(forKey: "token") as! String
    }
    else{
         token = ""
    }

    let headers = [
        "Authorization": "Bearer \(token)",
        "Accept": "application/json"
    ]


    let manager = Alamofire.SessionManager.default
    manager.session.configuration.timeoutIntervalForRequest = 120
    manager.request(url!, method: .post, parameters: params, headers: headers)
        .responseJSON
        {
            response in
            switch (response.result)
            {
            case .success:
                let jsonResponse = response.result.value as! NSDictionary
                print(jsonResponse)
                completion(jsonResponse)
                Utils().HideLoader()
            case .failure(let error):
                Utils().showAlert("Something went wrong")
                Utils().HideLoader()
                failure(error)
                break
        }
    }
}
Ishwar Hingu
  • 562
  • 7
  • 14
2

Update to Swift 4.2

This code is based on pixel's answer, and is meant as an update for Swift 4.2

let bodyData = "key1=value&key2=value&key3=value"
request.httpBody = bodyData.data(using: .utf8)
Ibrahim
  • 6,006
  • 3
  • 39
  • 50
-1
 var post:NSString = "api=myposts&userid=\(uid)&page_no=0&limit_no=10"

    NSLog("PostData: %@",post);

    var url1:NSURL = NSURL(string: url)!

    var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!

    var postLength:NSString = String( postData.length )

    var request:NSMutableURLRequest = NSMutableURLRequest(URL: url1)
    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")


    var reponseError: NSError?
    var response: NSURLResponse?

    var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

    if ( urlData != nil ) {
        let res = response as NSHTTPURLResponse!;

        NSLog("Response code: %ld", res.statusCode);

        if (res.statusCode >= 200 && res.statusCode < 300)
        {
            var responseData:NSString  = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!

            NSLog("Response ==> %@", responseData);

            var error: NSError?

            let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as NSDictionary


            let success:NSInteger = jsonData.valueForKey("error") as NSInteger

            //[jsonData[@"success"] integerValue];

            NSLog("Success: %ld", success);

            if(success == 0)
            {
                NSLog("Login SUCCESS");

                self.dataArr = jsonData.valueForKey("data") as NSMutableArray 
                self.table.reloadData()

            } else {

                NSLog("Login failed1");
            }

        } else {

            NSLog("Login failed2");

        }
    } else {

         NSLog("Login failed3");
    }

This will help you definitely

Mohit Tomar
  • 5,173
  • 2
  • 33
  • 40
  • Adding " request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")" made everything to work for me. Thanks. – Neela Oct 11 '17 at 21:55