DEV Community

Anis Ali Khan
Anis Ali Khan

Posted on

Tutorial 13: Observable Objects and Environment Objects in SwiftUI

Observable Objects and Environment Objects in SwiftUI

Introduction

In this tutorial, we'll explore ObservableObject and EnvironmentObject in SwiftUI, which are essential for managing state in your app. We'll use these concepts to build a simple iPhone game. By the end of this tutorial, you'll understand:

  • The difference between @State, @ObservedObject, and @EnvironmentObject
  • How to use ObservableObject to manage data
  • How to share data across views with EnvironmentObject
  • How to apply this knowledge to build a simple game in SwiftUI
  • How to apply SwiftUI in VS Code

Prerequisites

Before we begin, ensure you have:

  • Xcode installed (latest version recommended)
  • Swift knowledge (basic to intermediate level)
  • VS Code with the Swift extension installed (for alternative development)

Understanding SwiftUI State Management

@State

  • Used for simple state management inside a single view.
  • Automatically refreshes the view when the state changes.

Example:

struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button("Increment") {
                count += 1
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

@ObservedObject

  • Used when multiple views need to share state.
  • Requires a class conforming to ObservableObject.

Example:

class CounterModel: ObservableObject {
    @Published var count = 0
}

struct CounterView: View {
    @ObservedObject var model = CounterModel()

    var body: some View {
        VStack {
            Text("Count: \(model.count)")
            Button("Increment") {
                model.count += 1
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

@EnvironmentObject

  • Used to inject shared data into multiple views without explicitly passing it.
  • Requires a .environmentObject() modifier on a parent view.

Example:

class GameSettings: ObservableObject {
    @Published var score = 0
}

struct ScoreView: View {
    @EnvironmentObject var settings: GameSettings

    var body: some View {
        Text("Score: \(settings.score)")
    }
}
Enter fullscreen mode Exit fullscreen mode

Building a Simple Game: Tap The Circle

Step 1: Create a Game Model

class GameModel: ObservableObject {
    @Published var score = 0
    @Published var position = CGPoint(x: 100, y: 100)
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Build the Game View

struct GameView: View {
    @EnvironmentObject var game: GameModel

    var body: some View {
        ZStack {
            Color.blue.edgesIgnoringSafeArea(.all)
            Circle()
                .fill(Color.red)
                .frame(width: 50, height: 50)
                .position(game.position)
                .onTapGesture {
                    game.score += 1
                    game.position = CGPoint(x: CGFloat.random(in: 50...350), y: CGFloat.random(in: 50...700))
                }

            VStack {
                Text("Score: \(game.score)")
                    .font(.largeTitle)
                    .padding()
                Spacer()
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Setup the Root View

@main
struct MyApp: App {
    @StateObject private var game = GameModel()

    var body: some Scene {
        WindowGroup {
            GameView()
                .environmentObject(game)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this tutorial, you learned how to use @State, @ObservedObject, and @EnvironmentObject in SwiftUI. You also built a simple game that updates the UI dynamically using these concepts. Finally, you explored how to work with SwiftUI in VS Code.

With this knowledge, you can now build more complex and interactive SwiftUI applications!

Neon image

Serverless Postgres in 300ms (!)

10 free databases with autoscaling, scale-to-zero, and read replicas. Start building without infrastructure headaches. No credit card needed.

Try for Free →

Top comments (0)

Image of Stellar post

Check out Episode 1: How a Hackathon Project Became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

Retry later