AlamoFire asynchronous completionHandler for JSON request
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Alamofire requests are asynchronous by default, which means the network call starts now and the result arrives later through a completion handler. In modern Swift code, the most important decision is not whether the request is asynchronous, but how you want to decode the JSON and how you want to surface success and failure back to the rest of the app.
The Basic Pattern
With Alamofire, a request typically looks like this:
The closure passed to responseData is the completion handler. It runs after the request finishes and gives you a Result that is either:
- '
.successwith the payload' - '
.failurewith anAFError'
That means any code depending on the server response must live inside the completion path or be called from it.
Prefer Decodable for Typed JSON
For modern Alamofire code, strongly typed decoding is usually better than grabbing raw JSON dictionaries. A Decodable model makes the response contract clearer and avoids repeated casting.
Using the function:
This keeps the networking layer small and lets higher-level code react through one clean completion handler.
If You Really Need Raw JSON
Sometimes you do not have a stable response model yet, or the payload is too dynamic for Decodable to be the right first step. In that case, request raw data and decode it yourself.
This is more flexible, but it also pushes parsing errors and type checking back onto your code.
Wrap Alamofire in Your Own API
One of the cleanest ways to use completion handlers is to hide Alamofire behind a small service object. That keeps controllers and views from turning into long networking blocks.
Now a view controller can stay focused on UI behavior:
This is easier to test and easier to refactor later than scattering raw request code throughout the app.
Validation and Error Handling Matter
Without validate(), a request with an HTTP 404 or 500 can still arrive at the success side if the transport itself succeeded. For most JSON APIs, you want status validation first so the completion handler reflects application-level success more accurately.
You can also inspect the status code when needed:
That is useful when error behavior depends on specific server responses such as unauthorized or not found.
Completion Handlers and the Main Thread
The network work itself is asynchronous, but the UI still needs to be updated on the main thread. If your completion handler updates labels, table views, or view models that assume main-thread usage, make that explicit.
Alamofire already integrates cleanly with app code, but you should still be deliberate about where UI work happens and where parsing or business logic lives.
Common Pitfalls
- Trying to return the JSON value directly from the request function instead of using the completion handler.
- Using old raw-JSON patterns everywhere when
Decodablewould make the response safer and clearer. - Skipping
validate()and then treating HTTP error responses as successful requests. - Writing large controller methods full of networking and parsing logic instead of wrapping Alamofire in a service layer.
- Mixing UI updates and background parsing logic without being clear about the thread that owns the UI.
Summary
- Alamofire JSON requests are asynchronous, so dependent logic must flow through a completion handler.
- '
responseDecodableis usually the cleanest modern choice for JSON APIs with stable schemas.' - Use
responseDataand manual decoding only when you genuinely need raw or highly dynamic JSON. - Wrap requests in small service methods so the rest of the app sees a clean
Result-based API. - Add validation and explicit error handling so the completion path reflects real API success and failure.

