Part - 2 : Managing Navigation with AppState and Routes Instead of NavigationLink

1. Introduction

I initially started managing navigation in my iOS community app using NavigationLink. However, as the app grew, this approach quickly became messy and hard to maintain for a larger application.

After looking for a better alternative, I discovered AppState and Routes. They provide a cleaner and more scalable way to handle navigation in SwiftUI.

In this vlog, I’ll demonstrate how AppState and Routes work and how they helped me manage navigation more efficiently.


2. Problem: Navigation Becomes Messy

  • Passing NavigationLinks between multiple views gets complicated.

  • Conditional navigation and deep links are hard to manage.

  • State changes in one view don’t always reflect properly in others.


3. Solution: AppState + Routes

AppState

  • A shared observable object that tracks the current screen or route.

  • All views can observe AppState to respond to changes automatically.

Routes (Enum)

  • Central enum defining all possible routes:
import SwiftUI

enum Route: Hashable {
    case signup
    case login
    case profile
    case welcome
    case donationpost
    case homepage
    case feedaStray
}

class AppState: ObservableObject {
    @Published var routes: [Route] = [] {
        didSet {
            print("AppState.routes updated:", routes)
        }
    }
}
  • AppState keeps track of the current active route.

Navigation Flow

  • Instead of multiple NavigationLinks, updating AppState triggers navigation.

  • Views automatically react to route changes, keeping your code clean.


4. Example: Redirecting After Signup

private func signUp() async {
    do {
        let result = try await Auth.auth().createUser(withEmail: email, password: password)
        try await model.updateDisplayName(for: result.user, displayName: name)

        // Navigate to login screen
        appstate.routes.append(Route.login)

    } catch {
        errorMessage = error.localizedDescription
    }
}
  • Once the user signs up successfully, the AppState.routes is updated.

  • Views observing AppState automatically navigate to the login screen.


5. Conclusion

Using AppState and Routes helped me manage navigation in SwiftUI in a clean, centralized, and scalable way.

By keeping all navigation state in one place, views remain decoupled from navigation logic, making the app easier to maintain as it grows.

If you’re building SwiftUI apps, I encourage you to experiment with AppState + Routes — it’s a small change that can make a big difference.

0
Subscribe to my newsletter

Read articles from Tabassum Akter Nusrat directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tabassum Akter Nusrat
Tabassum Akter Nusrat

Former Android dev at Samsung R&D, now diving deep into iOS development. Writing daily about Swift Concurrency, SwiftUI, and the journey of building real-world apps. Passionate about clean architecture, mental health tech, and learning in public.