34 thoughts on “Making a POST request in Swift

  1. If you hit a lack of write permission at “gem install sinatra”, prefix with sudo i.e
    “sudo gem install sinatra” and enter your account password when prompted

  2. For the newbies amongst you, the following commands need to be written from the Terminal app.

    chmod +x api.rb
    gem install sinatra
    ./api.rb

    If you hit any issues with the 3rd line, firstly, be sure to cd to the directory you saved your api.rb file in from terminal and execute it. Secondly, if you’re receiving any bash errors, try the following command instead: ruby api.rb

  3. I literally copy paste this (with my url, of course) and didn’t work, i think the dictionary is not being attached to the request, can you help!?

      • I solved in a different way, this was my solution and I don’t know if I was supposed to do it that way but it worked.

        var params = createStringFromDictionary(dictRequest)
        var paramsLength = “\(countElements(params))”
        var requestBodyData = (params as NSString).dataUsingEncoding(NSUTF8StringEncoding)

        //var url = NSURL(string: “http://localhost:8888/json.php”)
        var url = NSURL(string: “http://23.239.30.54:8080/test/myLogin.html”)
        var request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = “POST”
        request.HTTPBody = requestBodyData
        request.addValue(paramsLength, forHTTPHeaderField: “Content-Length”)
        request.addValue(“application/json”, forHTTPHeaderField: “Accept”)
        request.addValue(“application/x-www-form-urlencoded”, forHTTPHeaderField: “Content-Type”)

        var connection = NSURLConnection(request: request, delegate: self, startImmediately: false)
        println(“Sending request”)
        connection.start()

        • This is my createStringFromDictionary function

          func createStringFromDictionary(dict: Dictionary) -> String {
          var params = String()
          for (key, value) in dict {
          params += “&” + key + “=” + value
          }
          return params
          }

        • Thanks Gerardo ,It worked for me.
          I was getting Null data on server side.
          it was because of server was accepting URL encoded data with parameter that were passed in.

            • Solved.
              removed :
              request.addValue(“application/json”, forHTTPHeaderField: “Content-Type”)
              request.addValue(“application/json”, forHTTPHeaderField: “Accept”)

              Added:
              request.addValue(“application/x-www-form-urlencoded”, forHTTPHeaderField:”Content-Type”);

  4. Hi there, thanks for the Swift tutorials! I’m just trying to get this code working but I keep getting the error:
    “EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0)”
    on the line:
    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in

    I’m getting a response from my server (PHP), and I’ve set the server to just print the contents of the POST, but there’s nothing being received in the POST.

    Any ideas what’s going on?

    • The issue is most likely on the line that deserializes the JSON, try removing that line and everything after it to confirm. Most likely your data type is different than that of the iTunes JSON.

  5. Somewhat of a newbie towards the REST API, I got this working successfully with a Flask back end (thanks for that), I’m just wondering what sorts of security are built into or need to be layered on top of your code? Sensitive information such as Username / Password combos, I would guess need to be encrypted somehow?

    Sorry if the answer is obvious, I’m a little new to the issue of security concerns, was just wondering what additional things I should look into if I am implementing this code.

    • Yeah you would want to send the credentials securely over HTTPS, you could also manually hash the passwords using an algorithm only you know on both the client and server. There’s many considerations when securing something like this, but it’s all a little outside the scope of these tutorials I think. I’d advise reading up on the Objective-C tutorials and porting over the considerations taken there.

  6. Great tutorial. Thanks! Is there a particular reason why you using closure to notify a caller of a success or failure? My first thought was to return a tuple with multiple values…

  7. Thanks, Jameson Quave

    It really helped me a lot.
    Now my final code looks like this .

    func createStringFromDictionary(dict: Dictionary) -> String {
    var params = String()
    for (key, value) in dict {
    params += “&” + key + “=” + value
    }
    return params
    }

    func post(params : Dictionary, url : String, postCompleted : (JsonNSDictionary: NSDictionary,JsonString:String) -> ()) {
    var request = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = “POST”
    var params2 = createStringFromDictionary(params)
    var paramsLength = “\(countElements(params2))”
    var requestBodyData = (params2 as NSString).dataUsingEncoding(NSUTF8StringEncoding)

    var err: NSError?
    request.HTTPBody = requestBodyData
    request.addValue(paramsLength, forHTTPHeaderField: “Content-Length”)
    request.addValue(“application/json”, forHTTPHeaderField: “Accept”)
    request.addValue(“application/x-www-form-urlencoded”, forHTTPHeaderField: “Content-Type”)

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
    println(“Response: \(response)”)
    var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
    println(“Body: \(strData)”)
    var err: NSError?
    var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
    postCompleted(JsonNSDictionary: json!,JsonString:strData!)

    })

    task.resume()
    }

  8. Hi everyone !

    Thanks for this tutorial, it helps me a lot !

    However, I have an issue if the JSON is a array like
    “[
    {
    “user”: {
    “name”: “nom”
    },
    “date”: “2015-02-16T14:13:12.434Z”
    }
    ]”

    Do you have some ideas ? Thanks a lot

    • Try deserializing this at the top level as shown in the tutorial, and then put a breakpoint in your code. This will show you what objects were created in memory on the debug window, so you can see how this JSON maps to Swift/Obj-C objects.

      For this, it will be something like:

      Array -> NSDictionary (user, data)
      “user” -> String
      “data” -> String

  9. I’m trying this in a console application, and it seems the post task is not being executed. It’s like the completionHandler passed into the task creation isn’t getting called. Is it possible for a console application to exit before the post task completes?

  10. Trying to do adapt this to a simple table I want to populate using my node.js api and swift. My table contains a varchar and a boolean. I can’t seem to make it work.

    var params = [“name”:”hurray!”, “works”:true] as Dictionary
    var err: NSError?
    request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err) //This line gets an error saying Cannot invoke dataWithJSONObject with an argument list of type Dictionary

    It only works if it’s Dictionary

    How do I make this work with non strings?

  11. Can you help me how can i adjust this code in that way so it could send a data to server when i login , and not when I’m running the app?
    I would be really grateful, i have so much problem to make that work!
    Thank you!

Comment