How to Send Post Parameters in Swift

HTTP Request in Swift with POST method

The key is that you want to:

  • set the httpMethod to POST;
  • optionally, set the Content-Type header, to specify how the request body was encoded, in case server might accept different types of requests;
  • optionally, set the Accept header, to request how the response body should be encoded, in case the server might generate different types of responses; and
  • set the httpBody to be properly encoded for the specific Content-Type; e.g. if application/x-www-form-urlencoded request, we need to percent-encode the body of the request.

E.g., in Swift 3 and later you can:

let url = URL(string: "https://httpbin.org/post")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
let parameters: [String: Any] = [
"id": 13,
"name": "Jack & Jill"
]
request.httpBody = parameters.percentEncoded()

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard
let data = data,
let response = response as? HTTPURLResponse,
error == nil
else { // check for fundamental networking error
print("error", error ?? URLError(.badServerResponse))
return
}

guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}

// do whatever you want with the `data`, e.g.:

do {
let responseObject = try JSONDecoder().decode(ResponseObject<Foo>.self, from: data)
print(responseObject)
} catch {
print(error) // parsing error

if let responseString = String(data: data, encoding: .utf8) {
print("responseString = \(responseString)")
} else {
print("unable to parse response as string")
}
}
}

task.resume()

Where the following extensions facilitate the percent-encoding request body, converting a Swift Dictionary to a application/x-www-form-urlencoded formatted Data:

extension Dictionary {
func percentEncoded() -> Data? {
map { key, value in
let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
.data(using: .utf8)
}
}

extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="

var allowed: CharacterSet = .urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}

And the following Decodable model objects facilitate the parsing of the application/json response using JSONDecoder:

// sample Decodable objects for https://httpbin.org

struct ResponseObject<T: Decodable>: Decodable {
let form: T // often the top level key is `data`, but in the case of https://httpbin.org, it echos the submission under the key `form`
}

struct Foo: Decodable {
let id: String
let name: String
}

This checks for both fundamental networking errors as well as high-level HTTP errors. This also properly percent escapes the parameters of the query.

Note, I used a name of Jack & Jill, to illustrate the proper x-www-form-urlencoded result of name=Jack%20%26%20Jill, which is “percent encoded” (i.e. the space is replaced with %20 and the & in the value is replaced with %26).


See previous revision of this answer for Swift 2 rendition.

Swift 5, make http post request

Below is the code for Post Method,using URLSession

let Url = String(format: "http://10.10.10.53:8080/sahambl/rest/sahamblsrv/userlogin")
guard let serviceUrl = URL(string: Url) else { return }
let parameters: [String: Any] = [
"request": [
"xusercode" : "YOUR USERCODE HERE",
"xpassword": "YOUR PASSWORD HERE"
]
]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}

How to send POST parameters in Swift?

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.

How to send a POST request through Swift?

I think you should pass your request instead of the url to session.dataTask

here is how my code looks like:

private let url = URL(string: "http://example.com/")!

func httpPost(jsonData: Data) {
if !jsonData.isEmpty {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData

URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
NSLog("open tasks: \(openTasks)")
}

let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in
NSLog("\(response)")
})
task.resume()
}
}

How can I make a post request in Swift that reads more than 1 parameter?

I don't think the JSON data you were providing in parameters was valid (I check using jsonlint.com) Try this:

func postRequest(classroomID: String, email: String, vote: String){

//declare parameter as a dictionary which contains string as key and value combination.
let parameters: [String:Any] = [
"classroomID": classroomID,
"LastUpdated": "2020-01-01",
"TheVoteData":[
"Email": email,
"TheVote": vote
]
]

//create the url with NSURL
let url = URL(string: "https://www.api-gateway/dynamoDB/resource")!

//now create the Request object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST

do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to data object and set it as request body
} catch let error {
print(error.localizedDescription)
}

//HTTP Headers
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: [])
//create dataTask using the session object to send data to the server
let task = URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print(dataString)
}
//Returns HHTP response if
if let httpResponse = response as? HTTPURLResponse {
print(httpResponse.statusCode)
}
}

task.resume()
}

POST Parameters in Swift

Try to do parameter as array.
var params=[Candto] ()

Then loop whenever you want and append your object to array.



Related Topics



Leave a reply



Submit