Send HTTP POST Request using Swift

HTTP POST request in Swift is a way to send data to a server. You use URLSession to create and send the request. You specify the URL, set the request method to POST, and include any necessary headers or body content. After sending the request, you handle the response in a completion handler.

In this tutorial, you will learn how to send HTTP POST requests using Swift.

To learn how to send HTTP GET requests, please read this tutorial: Sending HTTP GET Request in Swift.

Step 1: Creating a URL

First, you need to create a URL object representing the endpoint to which you want to send the POST request. You can create it using the URL initializer with a string that represents the URL.

let url = URL(string: "https://jsonplaceholder.typicode.com/todos")!

Step 2: Creating a URLRequest

Next, create a URLRequest object using the URL you just created. This object will be used to configure the details of your HTTP request.

var request = URLRequest(url: url)

Step 3: Setting the HTTP Method to POST

This step specifies that the request will be a POST request. The httpMethod property of the URLRequest object is set to "POST". POST requests are used to send data to a server to create/update a resource.

request.httpMethod = "POST"

Step 4: Adding Basic Authorization HTTP Request Header (Optional)

If the API you’re interacting with requires basic authentication, you need to provide the credentials. This is done by encoding the username and password in base64 and setting it in the Authorization header. The setValue method is used to set the header value.

let loginString = "YourUsername:YourPassword"
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")

Step 5: Adding Auth Token to HTTP Request Header (Optional)

Similar to basic authentication, if the API uses token-based authentication, you need to provide the token. This is done by setting the Authorization header with the value "Bearer YourToken", where YourToken should be replaced with the actual token.

request.setValue("Bearer YourToken", forHTTPHeaderField: "Authorization")

Step 6: Setting the Content-Type to application/json

This step is crucial when you’re sending JSON data to the server. You set the Content-Type header to "application/json" to inform the server that the request body contains JSON data.

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

Step 7: Creating the JSON Body

Create a Swift structure representing the data. You have to define the data you want to send in the request body. This is done by creating a Swift structure that conforms to the Codable protocol and encoding it into JSON data using JSONEncoder. The encoded data is then set as the httpBody of the URLRequest.

struct ToDo: Codable {
    let userId: Int
    let title: String
    let completed: Bool
}

let newTodo = ToDo(userId:  300, title: "My urgent task", completed: false)

do { 
   let jsonData = try JSONEncoder().encode(newTodo) 
   request.httpBody = jsonData 
} catch let error { 
   debugPrint(error.localizedDescription) 
} 

Step 8: Sending the HTTP POST Request

Finally, you send the POST request to the server using URLSession.shared.dataTask(with:completionHandler:). This method returns a URLSessionDataTask object, which you can use to resume the task. The completion handler is a closure that gets called when the request is complete, providing you with the response data, response object, and any error that occurred.

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
    if let error = error {
        print("Error: \(error)")
    } else if let data = data {
        let str = String(data: data, encoding: .utf8)
        print("Received data:\n\(str ?? "")")
    }
}
task.resume()

Complete Code Example

Here’s the complete code that ties all the steps together. It includes a SwiftUI view with a button that, when tapped, performs the HTTP POST request. The performHTTPPostRequest function encapsulates all the steps discussed above.

import SwiftUI

struct ToDo: Codable {
    let userId: Int
    let title: String
    let completed: Bool
}

struct ContentView: View {
    
    func performHTTPPostRequest() {
        let url = URL(string: "https://jsonplaceholder.typicode.com/todos")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"

        let loginString = "YourUsername:YourPassword"
        let loginData = loginString.data(using: String.Encoding.utf8)!
        let base64LoginString = loginData.base64EncodedString()
        request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
        request.setValue("Bearer YourToken", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let newTodo = ToDo(userId:  300, title: "My urgent task", completed: false)
        
        do {
            let jsonData = try JSONEncoder().encode(newTodo)
            request.httpBody = jsonData
        } catch let error {
            debugPrint(error.localizedDescription)
        }

        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("Error: \(error)")
            } else if let data = data {
                let str = String(data: data, encoding: .utf8)
                print("Received data:\n\(str ?? "")")
            }
        }
        task.resume()
    }

    var body: some View {
        VStack {
            Button("Perform Request", action: {
                performHTTPPostRequest()
            })
        }
    }
}
Send HTTP POST Request example in Swift

Conclusion

I hope this tutorial was helpful to you. You can also read this tutorial about HTTP GET requests in Swift

To learn more about Swift and to find other code examples, check the following page: Swift Code Examples.

Keep coding!