HTTP POST Request Example in Swift

In this tutorial, you will learn how to send HTTP Post Request in Swift and how to read HTTP Response and Response Body. This tutorial will cover:

  • Send HTTP Post Request,
  • Convert Query String request parameters to JSON,
  • Convert Swift structure to JSON,
  • Set HTTP Request Headers,
  • Read HTTP Response,
  • Read HTTP Response Headers,
  • Read HTTP Response Body as String,
  • Read HTTP Response Body as JSON

To learn how to send HTTP GET Request please read this tutorial: HTTP GET Request Example in Swift

Public RESTful Web Service Endpoint

In this tutorial, I will use public and free at the time of writing this tutorial RESTful Web Service: https://jsonplaceholder.typicode.com. This web service endpoint allows me to send HTTP Requests to it and get back JSON response. For example, if I open the following URL in the browser windows: https://jsonplaceholder.typicode.com/todos/1 I will get back the following JSON document:

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

I can also send HTTP Post Request to https://jsonplaceholder.typicode.com/todos and get back a created record. For example, if I send an HTTP Post request containing the following JSON payload in the body of HTTP Request:

{
  "userId": 300,
  "title": "delectus aut autem",
  "completed": false
}

I will get back a response similar to this:

{
  "userId": "300",
  "title": "My urgent task",
  "completed": "false",
  "id": 201
}

So let’s try and see how it works with Swift.

Send HTTP POST Request

Below is a very simple example of how you can send an HTTP POST Request in Swift. Please note the comments in the code.

// Prepare URL 
let url = URL(string: "https://jsonplaceholder.typicode.com/todos")
guard let requestUrl = url else { fatalError() }

// Prepare URL Request Object
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
 
// HTTP Request Parameters which will be sent in HTTP Request Body 
let postString = "userId=300&title=My urgent task&completed=false";

// Set HTTP Request Body
request.httpBody = postString.data(using: String.Encoding.utf8);

// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        
        // Check for Error 
        if let error = error {
            print("Error took place \(error)")
            return
        }
 
        // Convert HTTP Response Data to a String
        if let data = data, let dataString = String(data: data, encoding: .utf8) {
            print("Response data string:\n \(dataString)")
        }
}
task.resume()

Please note how in the code snippet above we convert the Data object to a String. The result of the above HTTP Post request should print out the following JSON string:

 {
  "userId": "300",
  "title": "My urgent task",
  "completed": "false",
  "id": 201
}

Here is how the code above looks in my Xcode Playground:

HTTP Post Request Example in Swift

Set HTTP Request Header

If your HTTP Request needs to contain specific HTTP Request Headers, then below is an example of how you can do it.

var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"

// Set HTTP Request Header
request.setValue("application/json", forHTTPHeaderField: "Accept")

You can set more than one header.

request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

Read HTTP Response Headers

Once you have received HTTP Response, you can then read from that HTTPURLResponse object all HTTP Request headers at once or if you know the HTTP request header name, then you can read the value of that specific header.

Read All Header Fields

let allHeaderFields:[AnyHashable : Any] = response.allHeaderFields
print("All headers: \(allHeaderFields)")

Read a Specific HTTP Header Value

let contentTypeHeader = response.value(forHTTPHeaderField: "Content-Type")

and here how it is being used when HTTP Response is received:

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
 
    if let response = response as? HTTPURLResponse {

        // Read all HTTP Response Headers
        print("All headers: \(response.allHeaderFields)")

        // Read a specific HTTP Response Header by name
        print("Specific header: \(response.value(forHTTPHeaderField: "Content-Type") ?? " header not found")")
    }
     
}
task.resume()

Read HTTP Response Body

When HTTP Response arrives, you will most likely need to read its HTTP Response Body. Use the below code snippet to convert the HTTP Response Body/Data to a human-readable String value.

if let data = data, let dataString = String(data: data, encoding: .utf8) {

    print("Response data string:\n \(dataString)")

}

and here how it looks if used with URLSession data task:

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
  
    if let data = data, let dataString = String(data: data, encoding: .utf8) {
        print("Response data string:\n \(dataString)")
    }
    
}
task.resume()

Swift Struct as Request Body

You can also send Swift structure in HTTP Response Body. For example, instead of sending HTTP Request parameters as we did in the example above  userId=300&title=My urgent task&completed=false, we can create a Swift structure and set it as HTTP Response body.

The following request parameters String could also be represented in the following way:

struct ToDoResponseModel: Codable {
    var userId: Int
    var id: Int?
    var title: String
    var completed: Bool
}
let newTodoItem = ToDoResponseModel(userId: 300, title: "Urgent task 2", completed: true)

Using the JSONEncoder() we can then encode the above Swift structure into JSON Data and set it as Request Body.

let jsonData = try JSONEncoder().encode(newTodoItem)
request.httpBody = jsonData

Note: Do not forget to set HTTP Headers: Accept and Content-Type to application/json.

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

For example:

struct ToDoResponseModel: Codable {
    var userId: Int
    var id: Int?
    var title: String
    var completed: Bool
}

let url = URL(string: "https://jsonplaceholder.typicode.com/todos")
guard let requestUrl = url else { fatalError() }

var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"

// Set HTTP Request Header
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

let newTodoItem = ToDoResponseModel(userId: 300, title: "Urgent task 2", completed: true)
let jsonData = try JSONEncoder().encode(newTodoItem)

request.httpBody = jsonData 

    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        
        if let error = error {
            print("Error took place \(error)")
            return
        }
        guard let data = data else {return}

        do{
            let todoItemModel = try JSONDecoder().decode(ToDoResponseModel.self, from: data)
            print("Response data:\n \(todoItemModel)")
            print("todoItemModel Title: \(todoItemModel.title)")
            print("todoItemModel id: \(todoItemModel.id ?? 0)")
        }catch let jsonErr{
            print(jsonErr)
       }

 
}
task.resume()

Covert Response Data into Swift Structure

Once the HTTP Response arrives, we can then decode the JSON Payload into a Swift Struct. In the code example above we have already done that. To convert data object container JSON string we will use JSONDecoder(). For example:

do{
    let todoItemModel = try JSONDecoder().decode(ToDoResponseModel.self, from: data)
    print("Response data:\n \(todoItemModel)")
    print("todoItemModel Title: \(todoItemModel.title)")
    print("todoItemModel id: \(todoItemModel.id ?? 0)")
}catch let jsonErr{
    print(jsonErr)
}

Here is how my code in Xcode playground looks now:

HTTP Post example in Swift

I hope this tutorial was helpful to you. Check other Swift tutorials on this web site and you will find a lot of useful code examples to use.

To learn how to send HTTP GET Request please read this tutorial: HTTP GET Request Example in Swift

Leave a Reply

Your email address will not be published. Required fields are marked *