2

I have to make a post request and receive a response in Swift. I need to add values to the request ​​in key-value pairs format and then I get an answer (0 or 1). I don't know how to add the Dictionary values to the request.:

    var url = NSURL(string:"www.myurl.com")
    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    var params = ["email":"\(txtEmail.text)", "passw":"\(txtPassword.text)"] as Dictionary
    let data = //HOW CAN I LOAD THE DATA TO THE HTTPBODY REQUEST??
    request.HTTPBody = data
    var connection = NSURLConnection(request: request, delegate: self, startImmediately: false)

Thanks in advance.

imj
  • 472
  • 1
  • 8
  • 24
  • 1
    See http://stackoverflow.com/a/25154803/1271826. I think this alternative `NSURLQueryItem` [solution](http://stackoverflow.com/a/27151324/1271826) is incredibly elegant and enticing if targeting iOS 8 only, but it doesn't handled `+` character properly (i.e. if there was `+` in the password, it would't work properly). – Rob Nov 29 '14 at 15:22
  • 1
    What format should the data be when it's sent? JSON? URL form encoded? @Rob's answer is helpful if URL form encoded, if JSON you can use `NSJSONSerialization`. – pwightman Nov 30 '14 at 06:10

2 Answers2

5

The solution. Thanks to @Rob :

func loginRequest(url:String, withParams params: [String: String?], postCompleted : (succeeded: Bool, msg: String) -> ()){
    var request = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    var err: NSError?
    var bodyData = ""
    for (key,value) in params{
        if (value == nil){ continue }
        let scapedKey = key.stringByAddingPercentEncodingWithAllowedCharacters(
            .URLHostAllowedCharacterSet())!
        let scapedValue = value!.stringByAddingPercentEncodingWithAllowedCharacters(
            .URLHostAllowedCharacterSet())!
        bodyData += "\(scapedKey)=\(scapedValue)&"
    }

    request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)

    var task = session.dataTaskWithRequest(request,
        completionHandler: {data, response, error -> Void in
            let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
            postCompleted(succeeded: true, msg: dataString!)
    })
    task.resume()
}

Then, I call the function and I can know if the user is correct:

        self.loginRequest("http:myurl.com",
            withParams: ["email":"email","passw":"passw"])
        {
            (succeeded: Bool, msg: String) -> () in
            if(succeeded) {
                if msg == "0"
                {
                    //Incorrect data...
                }
                else
                {
                    //The login it's ok...
                }
            }
        }
imj
  • 472
  • 1
  • 8
  • 24
1

Updated the code for Swift 4 + small improvements. Based on @imj work.

/// Converts the dictionary to key values
func convertToParameters(_ params: [String: String?]) -> String {
    var paramList: [String] = []

    for (key, value) in params {
        guard let value = value else {
            continue
        }

        guard let scapedKey = key.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
            print("Failed to convert key \(key)")
            continue
        }

        guard let scapedValue = value.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
            print("Failed to convert value \(value)")
            continue
        }

        paramList.append("\(scapedKey)=\(scapedValue)")
    }

    return paramList.joined(separator: "&")
}
Pion
  • 708
  • 9
  • 21