Skip to Content
Course content

164: The Singleton Pattern in Swift

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine your town has one, and only one, central post office. It doesn't matter where you live in the city; if you want to mail a letter, you go to that specific building. You can't just decide to build your own personal post office in your backyard because the town's entire logistics system is designed around that one central hub. If you tried to create a second one, it wouldn't have the official keys, the sorting machines, or the legal authority to move mail. Everyone shares the same instance of the post office.

In Swift, the Singleton pattern is exactly that. It's a way to ensure that a class has only one instance and provides a global point of access to it. Let's map that analogy to the code:

  • The Post Office Building: This is your class.
  • The Official Address: This is a static property (usually called shared) that lets anyone find the instance.
  • The "No Building More" Rule: This is a private initializer that prevents other parts of your code from creating new copies of the class.

The Single Point of Control

I've seen a lot of developers struggle with state management where three different parts of an app are trying to track the user's login status in three different objects. It's a nightmare to debug. This is where a Singleton shines. Let's look at a NetworkConfiguration manager. You wouldn't want different parts of your app using different API keys or timeout settings; you want one source of truth.

class NetworkConfiguration {
    // The single, shared instance
    static let shared = NetworkConfiguration()
    
    var apiKey: String = "ABC-123-XYZ"
    var timeoutInterval: TimeInterval = 30.0
    
    // This is the most important part: the private init
    private init() {
        // Setup logic goes here
    }
}

Locking the Front Door

Notice that private init(). If I left that initializer public, any other developer on the team could just write let config = NetworkConfiguration() and suddenly we have two different configurations running in the same app. By marking it private, I'm telling the compiler, "Nobody is allowed to instantiate this class from the outside." The only way to get into the building is through the shared door I already provided.

Using the Shared Instance

Because the instance is static, you don't need to pass it around through every single function call or initializer in your app. You just call it wherever you need it.

func fetchData() {
    let key = NetworkConfiguration.shared.apiKey
    print("Fetching data using key: \(key)")
}

It's clean, it's fast, and it's predictable. However, a word of caution from my own experience: don't overdo it. It's tempting to make every manager class a Singleton. But when you do that, you're essentially creating global state, which can make unit testing a bit of a headache because the state persists between tests. Use them for things that truly are unique—like a database connection, a hardware manager, or a user session.




📋 Practical Task

Build a Global UserSessionManager

You need to create a system that tracks the currently logged-in user across the entire app. If the user changes their profile name on the Settings screen, the Home screen should reflect that change immediately because they are both looking at the same object.

Requirements:

  • Create a class named UserSessionManager.
  • Implement the Singleton pattern so that only one instance can ever exist.
  • Add a property username: String (initialize it as "Guest").
  • Add a property isLoggedIn: Bool (initialize it as false).
  • Create a function login(as name: String) that updates both properties.

Test your implementation:

  1. Try to create a new instance of UserSessionManager using UserSessionManager() and verify that the compiler throws an error.
  2. Access the shared instance and call login(as: "SwiftDeveloper").
  3. Print the username from a different part of your code using the shared instance to ensure the name was updated globally.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.