Skip to content
The App Code
How-to

Make a GET Request in Swift

Fetch data from a URL using URLSession's async/await API and decode the response.

Also known as: URLSession GET Swift, Swift async HTTP

intermediate

URLSession.shared.data(from:) is an async call that returns the body and response together, letting you await a GET request without completion handlers.

What it is

Since iOS 15 / macOS 12, URLSession exposes async methods that replace the older callback style. try await session.data(from: url) returns a tuple of (Data, URLResponse). Cast the response to HTTPURLResponse to inspect the status code, then decode the body.

This runs off the main thread automatically, so you can await it from a task and update UI afterwards. Because it can throw and can be cancelled, call it inside a do/catch within an async context.

Worked example

import Foundation

struct Post: Codable { let id: Int; let title: String }

func fetchPost() async throws -> Post {
    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")!
    let (data, response) = try await URLSession.shared.data(from: url)

    guard let http = response as? HTTPURLResponse, http.statusCode == 200 else {
        throw URLError(.badServerResponse)
    }
    return try JSONDecoder().decode(Post.self, from: data)
}

Task {
    let post = try await fetchPost()
    print(post.title)
}

Failure mode — when it misleads

data(from:) does not throw on 4xx/5xx status codes — it only throws on transport failures. You must check HTTPURLResponse.statusCode yourself, otherwise you'll try to decode an error page as your model and get a confusing decoding error instead of the real HTTP failure.

Sources & further reading