How in Swift declare global variables or use shared data management approaches to use data across your entire app!

Diego Perez Salas
2 min readMar 26, 2024

--

Here are four ways to declare global variables or use shared data management approaches to use data across your entire app:

1. Global Variables

You can simply declare a variable outside of any struct or class at the top level of your Swift file, making it accessible from anywhere in your app. However, this approach is generally discouraged for non-constant data due to issues with data management, testing, and debugging.

var globalCounter: Int = 0

2. Singleton Pattern

A more controlled way to have app-wide accessible data is using the Singleton pattern. A Singleton class ensures that only one instance of a class is created and provides a global access point to that instance. It’s commonly used for managing shared resources or settings.

class AppData {
static let shared = AppData()
var counter: Int = 0

private init() {} // Prevents others from creating instances
}

To access or modify the counter from anywhere, you would use AppData.shared.counter.

3. EnvironmentObject

In SwiftUI, @EnvironmentObject is a property wrapper that allows you to share an observable object among all views in the app without having to pass it explicitly through each view. This is especially useful for data or settings that are used across many parts of your app.

First, create an observable class that conforms to ObservableObject:

class GlobalSettings: ObservableObject {
@Published var counter: Int = 0
}

Then, in your App struct, attach the object to the environment:

@main
struct MyApp: App {
var settings = GlobalSettings()

var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(settings)
}
}
}

Views that need access to GlobalSettings can now declare an @EnvironmentObject property:

struct SomeView: View {
@EnvironmentObject var settings: GlobalSettings

var body: some View {
// Use `settings.counter` here
}
}

4. @AppStorage and UserDefaults

For simple data types, you might want to use @AppStorage, which provides a property wrapper for automatically reading and writing to the UserDefaults, making it persistent across app launches.

struct ContentView: View {
@AppStorage("counter") var counter: Int = 0

var body: some View {
// Use `counter` here
}
}

Choosing the Right Approach

  • Use global variables for constants or configuration that doesn’t change.
  • The Singleton pattern is useful for shared resources or services, like a network manager.
  • EnvironmentObject is ideal for shared data that needs to be observed across many views.
  • @AppStorage and UserDefaults are suitable for storing user preferences or simple persistent data.

Each method has its use cases, advantages, and drawbacks. Choosing the right approach depends on your specific needs, such as the type of data you’re sharing, how widely it’s used, and whether it needs to be observed for changes.

--

--