Let's think about it this way for a second
A SwiftUI View struct doesn't have a big set of lifecycle callbacks like UIKit's Activity/ViewController lifecycle (`onCreate`, `onResume`, etc.) — the two most commonly used modifiers are `onAppear { }` (runs every time the View appears on screen) and `onDisappear { }` (runs every time the View disappears from screen). Data fetching (API calls) is typically triggered inside `onAppear`.
Let's connect this to a real-world scenario
If `WeatherScreen` has `.onAppear { viewModel.fetchWeather() }` written on it — the weather data gets automatically fetched every time the user lands on this screen. If you want to cancel an ongoing network task when the user leaves the screen, you can add `.onDisappear { viewModel.cancelFetch() }`.
Let's look at it together
struct WeatherScreen: View {
@State private var weather: WeatherResponse?
var body: some View {
VStack {
if let weather {
Text("\(weather.tempCelsius)°C")
} else {
ProgressView()
}
}
.onAppear {
Task {
weather = try? await fetchWeather(city: "Yangon")
}
}
}
}Every time you land on the screen, you'll see a loading spinner followed by the weather data being automatically fetched and displayed.5-minute try-it
Run `WeatherScreen` and test it by adding `print("appeared")` to the fetch logic inside `onAppear` — confirm that 'appeared' shows up again in the console every time you return to the screen.
A quick heads-up
`onAppear` isn't the same as 'the View being created for the first time' — watch out, because `onAppear` can fire repeatedly every time you enter/leave a screen inside a NavigationStack.