Thuta Learning
ProjectsMobile Developmentintermediate

Project — Weather App (URLSession + async/await)

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Understand Project — Weather App (URLSession + async/await) with zero fear
  • Run the Xcode/SwiftUI code yourself
  • Apply this concept in a real project right away

Let's think about it this way for a second

In a network-based app, you have to handle three states in the UI — loading (data is being fetched), success (data has arrived), and error (the network call failed). The user should always know 'what's going on' — you can't just leave a blank screen. A common pattern for managing this is `enum WeatherUiState { case loading; case success(WeatherResponse); case error(String) }` (similar to Android's sealed class pattern).

Let's connect this to a real-world scenario

When you type a city name into the TextField and tap the Search button — the ViewModel sets `state = .loading` and calls `fetchWeather(city:)` inside a `Task { }`. On success it sets `state = .success(response)`; on failure (network down, city not found) it sets `state = .error("...")`. The View then renders differently depending on the state with `switch state { case .loading: ProgressView(); case .success(let data): WeatherCard(data); case .error(let msg): Text(msg) }`.

Let's walk through it together

swift
enum WeatherUiState {
    case loading
    case success(WeatherResponse)
    case error(String)
}

@MainActor
class WeatherViewModel: ObservableObject {
    @Published var state: WeatherUiState = .loading

    func search(city: String) async {
        state = .loading
        do {
            let weather = try await fetchWeather(city: city)
            state = .success(weather)
        } catch {
            state = .error("Could not load weather for \(city)")
        }
    }
}
You should see
Type in a city name and search, and you should see a loading spinner followed by the weather data (or an error message) on screen.

5-minute try-it

Build the Weather app yourself (search TextField + Loading/Success/Error UI) — try typing an invalid city name to trigger the error state.

A quick word of caution

Watch out for API rate limits (free-tier weather APIs usually cap requests per day) — repeatedly sending requests while testing can easily blow past the limit.

Easy traps

  • Leaving the error state as one generic 'Something went wrong' message — users understand much better when you distinguish between a network error and a city-not-found error
  • Only testing the loading state on the Simulator's fast network — you should also test slow/no-network scenarios using Xcode's Network Link Conditioner

Now try it yourself

Build the Weather app yourself (search TextField + Loading/Success/Error UI) — try typing an invalid city name to trigger the error state.

You'll know it worked when: Type in a city name and search, and you should see a loading spinner followed by the weather data (or an error message) on screen.

Project — Weather App (URLSession + async/await) | Thuta Learning