Networking with URLSession & async/await

Fetch real data from the web. You'll call URLSession.shared.data(from:) with async/await , decode JSON into Swift types with Codable , check HTTP status codes, and handle errors cleanly.

Learn Networking with URLSession & async/await in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise…

Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

📊 The Networking Pieces

Piece

Role

URL

Where to fetch from

data(from:)

Async fetch, returns (Data, URLResponse)

HTTPURLResponse

Exposes the statusCode

Codable

Model that maps to JSON

JSONDecoder

Turns Data into your model

1️⃣ Fetch and Decode

The core flow is three lines: build a URL , await the data, and decode it into a Codable model whose properties match the JSON keys.

Your turn. Fill in the protocol, the await keyword, and the decoder type.

2️⃣ Check the Status Code

A 404 or 500 still returns Data rather than throwing, so always cast to HTTPURLResponse and confirm the code is in the 200..<300 range before trusting the body.

3️⃣ Handle Errors

Networking can fail in two ways: the request itself ( URLError ) or the parsing ( DecodingError ). Catch them separately so you can show the right message.

Now you try. Fill in the error-handling keywords.

Pro Tips

Common Errors (and the fix)

📋 Quick Reference

Step

Code

Result

Build URL

URL(string: "…")!

an endpoint

Fetch

try await …data(from:url)

(Data,Response)

Status

resp as? HTTPURLResponse

statusCode

Decode

JSONDecoder().decode(T.self,…)

a model

Errors

do { try … } catch { … }

handled

Frequently Asked Questions

Mini-Challenge: Fetch and Validate

Write a full fetch that checks the status code and decodes a Todo, then report whether it's completed.

🎉 Lesson Complete!

Practice quiz

Which URLSession method fetches data using async/await?

  • URLSession.shared.data(from:)
  • URLSession.fetch()
  • URLSession.get()
  • URLSession.load()

Answer: URLSession.shared.data(from:). data(from:) is the async method that returns (Data, URLResponse).

What does URLSession.shared.data(from:) return?

  • Just Data
  • A String
  • A tuple of (Data, URLResponse)
  • An Int status code

Answer: A tuple of (Data, URLResponse). It returns a tuple containing the response Data and the URLResponse.

Which protocol must a type adopt to be decoded from JSON?

  • Hashable
  • Decodable (or Codable)
  • Equatable
  • Identifiable

Answer: Decodable (or Codable). Decodable enables decoding; Codable is Decodable plus Encodable.

Which object turns JSON Data into a Swift value?

  • JSONSerialization only
  • JSONEncoder
  • PropertyListDecoder
  • JSONDecoder

Answer: JSONDecoder. JSONDecoder().decode(_:from:) decodes JSON Data into a Decodable type.

To read the HTTP status code, you cast the response to...

  • URLRequest
  • HTTPURLResponse
  • URLComponents
  • URLCache

Answer: HTTPURLResponse. Casting URLResponse to HTTPURLResponse exposes the statusCode.

Which status code range generally indicates success?

  • 100–199
  • 400–499
  • 200–299
  • 500–599

Answer: 200–299. 2xx codes indicate a successful HTTP response.

How do you handle errors from data(from:)?

  • Use try/catch because it can throw
  • Ignore them
  • Use a guard with no try
  • They never fail

Answer: Use try/catch because it can throw. data(from:) is async throws, so you call it with try inside a do/catch.

What does a URLError typically represent?

  • A decoding mistake
  • A nil optional
  • A type cast error
  • A networking failure such as no connection

Answer: A networking failure such as no connection. URLError describes networking-level failures like timeouts or no internet.

What does JSONDecoder throw on a shape mismatch?

  • Nothing
  • A DecodingError
  • A URLError
  • A fatalError

Answer: A DecodingError. Mismatched JSON throws a DecodingError such as keyNotFound or typeMismatch.

Why mark a fetching function async throws?

  • For styling
  • To run on the main thread
  • So it can await the request and propagate failures
  • To make it Sendable

Answer: So it can await the request and propagate failures. async lets it await the network call; throws lets it forward errors to the caller.

Continue this course