SWIFT

Swift API Fetch: Syntax, Usage, and Examples

A Swift API fetch lets your app connect to external web services to send or receive data. Whether you're building an iOS weather app, a social media feed, or a movie browser, using API fetch in Swift is how you communicate with back-end systems. It’s a crucial part of working with real-time or cloud-based data in any Swift-based application.

How to Use API Fetch in Swift

You typically use URLSession to perform an API fetch in Swift. This allows you to make HTTP requests (GET, POST, PUT, DELETE, etc.) and handle responses asynchronously.

Here’s the basic syntax for a Swift API fetch using URLSession:

if let url = URL(string: "https://api.example.com/data") {
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let data = data {
            // Handle the data
            print(String(data: data, encoding: .utf8)!)
        } else if let error = error {
            print("Error: \(error)")
        }
    }
    task.resume()
}

This snippet sends a GET request and logs the raw response.

Using Decodable for Clean Parsing

If the API returns JSON, it’s best to decode the data into Swift structs:

struct User: Decodable {
    let id: Int
    let name: String
}

if let url = URL(string: "https://api.example.com/user") {
    URLSession.shared.dataTask(with: url) { data, _, error in
        guard let data = data else { return }

        if let user = try? JSONDecoder().decode(User.self, from: data) {
            print("User: \(user.name)")
        }
    }.resume()
}

Using Decodable with JSONDecoder makes the data easy to work with.

When to Use Swift API Fetch

You’ll use API fetch in Swift when:

  • You need to retrieve data from an external server, like a list of items, posts, or users.
  • You're submitting data, such as forms, authentication credentials, or payment info.
  • You’re creating apps that depend on real-time or dynamic content.
  • You want to sync data between your app and a cloud service or database.
  • You’re integrating with third-party APIs like weather, maps, or social media.

Whether you're working with REST APIs, GraphQL, or your own backend, a Swift API fetch bridges the gap between the UI and external data sources.

Examples of API Fetch Swift Use Cases

Fetching Weather Data

struct Weather: Decodable {
    let temperature: Double
}

func fetchWeather() {
    guard let url = URL(string: "https://api.weather.com/temp") else { return }

    URLSession.shared.dataTask(with: url) { data, _, _ in
        guard let data = data else { return }

        if let result = try? JSONDecoder().decode(Weather.self, from: data) {
            print("Temperature: \(result.temperature)°C")
        }
    }.resume()
}

Here, the Swift API fetch retrieves live weather data and decodes it into a model.

Sending a POST Request

struct Message: Encodable {
    let content: String
}

func sendMessage(_ text: String) {
    guard let url = URL(string: "https://api.example.com/send") else { return }

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

    let message = Message(content: text)
    request.httpBody = try? JSONEncoder().encode(message)

    URLSession.shared.dataTask(with: request) { data, _, _ in
        if let data = data {
            print("Server response: \(String(data: data, encoding: .utf8) ?? "")")
        }
    }.resume()
}

POST requests let you submit data to the server, which is common in chat apps, forms, and authentication.

Handle HTTP Errors Gracefully

URLSession.shared.dataTask(with: someURL) { data, response, error in
    if let httpResponse = response as? HTTPURLResponse {
        switch httpResponse.statusCode {
        case 200...299:
            print("Success")
        case 400...499:
            print("Client error")
        case 500...599:
            print("Server error")
        default:
            print("Unknown response")
        }
    }
}.resume()

Always check the status code to understand what the server is trying to tell you.

Learn More About API Fetch in Swift

Working with Async/Await

Swift’s async/await makes fetching data more readable. With iOS 15+, you can use it like this:

func fetchUser() async {
    guard let url = URL(string: "https://api.example.com/user") else { return }

    do {
        let (data, _) = try await URLSession.shared.data(from: url)
        let user = try JSONDecoder().decode(User.self, from: data)
        print(user)
    } catch {
        print("Error: \(error)")
    }
}

This approach looks cleaner and avoids nested callbacks.

Using Combine for API Fetch

If you're working in a reactive context, Combine lets you fetch and handle responses as streams:

import Combine

struct Post: Decodable {
    let title: String
}

var cancellables = Set<AnyCancellable>()

func fetchPosts() {
    guard let url = URL(string: "https://api.example.com/posts") else { return }

    URLSession.shared.dataTaskPublisher(for: url)
        .map(\.data)
        .decode(type: [Post].self, decoder: JSONDecoder())
        .sink(receiveCompletion: { print($0) },
              receiveValue: { posts in
                  print(posts.map(\.title))
              })
        .store(in: &cancellables)
}

Combine is great for chaining asynchronous tasks or updating UI with reactive bindings.

Using Swift Concurrency with MainActor

If you're updating the UI after a fetch, make sure it happens on the main thread:

@MainActor
func updateUI(with user: User) {
    nameLabel.text = user.name
}

Calling UI updates directly after a background network task can cause issues if not properly routed.

Authentication and Headers

Most APIs require tokens or custom headers. You can include these in your request:

var request = URLRequest(url: someURL)
request.setValue("Bearer YOUR_API_TOKEN", forHTTPHeaderField: "Authorization")

This works for OAuth2, custom headers, or internal APIs.

Uploading Files via API

You can upload files using multipart/form-data, often needed for avatars or documents.

While more complex, several libraries like Alamofire make it easier, or you can construct your own body with boundary strings and proper content types.

Using URLComponents for Query Parameters

Rather than hardcoding URL strings, use URLComponents to add search or filter parameters safely:

var components = URLComponents(string: "https://api.example.com/search")
components?.queryItems = [URLQueryItem(name: "q", value: "swift")]

if let url = components?.url {
    URLSession.shared.dataTask(with: url) { data, _, _ in
        print(data ?? Data())
    }.resume()
}

This helps avoid malformed URLs and keeps the logic readable.

Best Practices for API Fetch Swift

  • Always validate the URL before creating the request.
  • Use Codable to map JSON responses into Swift structs cleanly.
  • Handle errors gracefully—network errors, decoding issues, or HTTP errors.
  • Use URLSession.shared for simple tasks or configure your own URLSession for more control.
  • If needed, cache responses to reduce API load or support offline access.
  • Secure your tokens and avoid hardcoding them in your codebase.
  • Don’t forget to run UI updates on the main thread.
  • Keep the API logic separate from UI code by using ViewModels or services.

A Swift API fetch connects your app to the data that drives it. You can start simple with URLSession or go advanced with async/await, Combine, and custom services. With good error handling, decoding, and separation of concerns, your API fetch logic in Swift will be easy to scale, debug, and maintain.

Learn to Code in Swift for Free
Start learning now
button icon
To advance beyond this tutorial and learn Swift by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH