iOS how to perform a HTTP POST request?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
On iOS, the standard way to perform an HTTP POST request is to build a URLRequest, set its method to POST, attach a body, and send it with URLSession. The details matter because servers usually expect specific headers and body formats such as JSON or form-encoded data.
Most modern Swift code uses URLSession directly. If you understand URLRequest, status-code handling, and JSON encoding, you can build the majority of POST calls without another networking library.
Build a JSON POST Request
A JSON API call typically needs a URL, the POST method, a Content-Type header, and a JSON-encoded body.
This example posts JSON to a public echo endpoint so you can run it and inspect the returned body. In a real app, replace the URL and payload model with your actual API contract.
Call It from UIKit Code
If you are inside a view controller, launch the async function from a task.
If the request result should update the UI, move those updates back onto the main actor. Networking itself does not need the main thread, but UIKit does.
Handle Status Codes and Response Data
Do not assume every completed request was successful. URLSession only throws for transport-level failures such as connectivity problems. A server can still return 400, 401, or 500 and the call will technically complete.
If the server returns JSON, decode it with JSONDecoder rather than manually parsing strings. That keeps the code safer and easier to maintain.
POST Form Data When the API Requires It
Not every server expects JSON. Some endpoints still use URL-encoded form bodies.
The request body format must match what the server expects. Sending JSON to a form endpoint, or the reverse, often leads to confusing validation errors.
Completion-Handler Version for Older Codebases
If your project is not using Swift concurrency yet, URLSession.dataTask still works well.
This is still common in existing UIKit projects, especially when code was written before async and await support.
Common Pitfalls
The most common mistake is forgetting task.resume() when using completion handlers. Without it, the request is configured but never starts.
Another issue is sending a body without setting the correct Content-Type header. Many APIs will reject the request or parse it incorrectly.
Developers also sometimes treat every non-throwing call as success and forget to inspect the HTTP status code. That hides server-side failures.
Finally, make sure your endpoint uses https in production. Plain http URLs can be blocked by App Transport Security unless you add exceptions, and those exceptions should be deliberate rather than casual defaults.
Summary
- Build POST calls with
URLRequestand send them throughURLSession. - Set the method, headers, and body to match the API contract exactly.
- Check HTTP status codes in addition to transport errors.
- Use JSON encoding for JSON APIs and form encoding only when the endpoint expects it.
- Update UIKit views on the main actor after the network response is processed.

