← All courses

App Structure & Lifecycle

🗓 May 31, 2026 ⏱ 2 min read

The @main App entry point

A SwiftUI app starts from a single struct marked @main that conforms to the App protocol. There is no AppDelegate to wire up — this struct describes your app’s windows and starting screen.

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()      // the first screen
        }
    }
}

What is a Scene?

A Scene represents a part of your app’s UI that the system manages — most commonly a WindowGroup (a window of your content). On iPad and Mac, a WindowGroup can have multiple windows; on iPhone it’s one. This abstraction is how one codebase adapts across Apple platforms.

Reacting to the app lifecycle

iOS moves your app between states: active (in front, interactive), inactive (transitioning, e.g. a call banner), and background (not visible). You can react to these with the scenePhase environment value — useful for pausing timers or saving data when the user leaves.

struct MyApp: App {
    @Environment(\.scenePhase) private var scenePhase
    var body: some Scene {
        WindowGroup { ContentView() }
            .onChange(of: scenePhase) { _, newPhase in
                switch newPhase {
                case .active:    print("App is active")
                case .inactive:  print("App is inactive")
                case .background: saveData()   // good time to persist
                @unknown default: break
                }
            }
    }
}

App-wide setup and shared data

The App struct is also where you inject app-wide dependencies (an @StateObject for shared data) into the environment so every screen can read them.

@main
struct MyApp: App {
    @StateObject private var session = UserSession()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(session)   // available everywhere
        }
    }
}

Why this matters

Understanding the entry point and lifecycle lets you do the right thing at the right time: set up shared state once at launch, and save work or pause activity when the app goes to the background (the system may suspend or terminate it at any point).

Common mistakes

  • Trying to put startup logic in a view’s body instead of the App struct.
  • Not saving important data when entering the background.
  • Assuming the app keeps running in the background — it usually doesn’t.
Summary: A SwiftUI app starts from a @main App struct made of Scenes (usually a WindowGroup). Inject shared data here, and use scenePhase to react to active/inactive/background changes — especially to save data when leaving.