How to make HTTP PUT request with JSON as Data in Swift

In this tutorial we’re going to learn how to make an HTTP PUT request using uploadTask(with:from:) method by sending a JSON dictionary as a Data structure. In general, PUT request is great for creating a new resource or overwriting it.

As you can see from Apple’s documentation, the uploadTask method looks like this:

func uploadTask(with request: URLRequest, from bodyData: Data) -> URLSessionUploadTask

It takes two arguments, a URLRequest and a Data object constituting body for that request. With that, we first need to create an appropriate URLRequest for making a PUT request and then we need to convert our JSON dictionary into the Data structure.

For the purpose of this tutorial we’re going to use Postman Echo.

Postman Echo is service you can use to test your REST clients and make sample API calls. It provides endpoints for GET, POST, PUT, various auth mechanisms and other utility endpoints.


Prepare a URLRequest for PUT request

let baseURL = URL(string: "https://postman-echo.com")!
let fullURL = baseURL.appendingPathComponent("/put”)

var request = URLRequest(url: fullURL)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = [
    "Content-Type": "application/json",
    "Accept": "application/json"
]

Convert JSON dictionary to Data structure

let jsonDictionary: [String: String] = [
    "title": "Make PUT request with JSON Data in Swift",
]

let data = try! JSONSerialization.data(withJSONObject: jsonDictionary, options: .prettyPrinted)

Make PUT request and handle errors

URLSession.shared.uploadTask(with: request, from: data) { (responseData, response, error) in
    if let error = error {
        print("Error making PUT request: \(error.localizedDescription)")
        return
    }
    
    if let responseCode = (response as? HTTPURLResponse)?.statusCode, let responseData = responseData {
        guard responseCode == 200 else {
            print("Invalid response code: \(responseCode)")
            return
        }
        
        if let responseJSONData = try? JSONSerialization.jsonObject(with: responseData, options: .allowFragments) {
            print("Response JSON data = \(responseJSONData)")
        }
    }
}.resume()

Related tutorials: