Singleton Class in Swift

In this tutorial, you will learn how to implement the Singleton design pattern in Swift.

Introduction to Singleton Design Pattern

The Singleton design pattern guarantees that only one object of a class will exist in a system. This is done in Swift by creating a class with a private initializer. The private initializer ensures that no other part of the code can create a new instance of the class, which maintains the uniqueness of the object.

In addition to the private initializer, the class provides a static instance of itself. This static instance is the single object that will exist during the runtime of the system. By having a static instance, a centralized access point is established, which is crucial for managing shared resources across various parts of an application.

Lastly, the Singleton pattern is useful when there’s a need for a single access point to certain resources. It ensures consistent behaviour and state management across the application, making the Singleton pattern a practical choice in Swift programming for maintaining order and predictability in system operations.

Creating Singleton Class in Swift

The code snippet below is an example of a Singleton class in Swift. Take a look at how this class is organized. Below this code snippet, I will explain what exactly makes this class a Singleton.

// Creating a Singleton
// Only one instance of this class can be created
class CloudCodeExecutor {

    // Declare class instance property
    static let sharedInstance = CloudCodeExecutor()
   
    // Declare an initializer 
    // Because this class is singleton only one instance of this class can be created
    private init() {
        print("CloudCodeExecutor has been initialized")
    }

    // Add a function
    func processCloudCodeOperation() {
        print("Started processing cloud code operation")

        // Your other code here
    }
}


// Call function of Singleton class
CloudCodeExecutor.sharedInstance.processCloudCodeOperation()

// Call cloud code operation function again
CloudCodeExecutor.sharedInstance.processCloudCodeOperation()

// And again to see that class initializer was called only once
CloudCodeExecutor.sharedInstance.processCloudCodeOperation()

In the provided code snippet, the CloudCodeExecutor class is set up as a Singleton class in Swift. Here are the parts that make this class a Singleton:

Private Initializer

private init() {
    print("CloudCodeExecutor has been initialized")
}

Here, private init() is a special setup that tells Swift to block any other parts of the code from creating a new CloudCodeExecutor. By marking the initializer as private, we ensure that no one else can create a new instance, making sure there’s only one CloudCodeExecutor throughout the app.

Static Instance Property

static let sharedInstance = CloudCodeExecutor()

This line creates a single, shared instance of CloudCodeExecutor. The word static means that this sharedInstance is tied to the class itself, not to any particular object created from the class. So, whenever we refer to CloudCodeExecutor.sharedInstance, we are talking about the same single instance, no matter where in the code we are.

These two parts work together to create a Singleton class in Swift. The private initializer keeps other code from creating new CloudCodeExecutor instances and the static instance property provides a way to access a single CloudCodeExecutor instance wherever we need to in the code.

Accessing the Singleton Instance

In the earlier section, we created a Singleton class named CloudCodeExecutor. Now, I’ll demonstrate how to access and use the single instance of this class that our Singleton setup permits.

Accessing the Singleton instance is quite straightforward due to the static property sharedInstance that we defined within the CloudCodeExecutor class. This property serves as our access point to interact with the Singleton instance.

Here’s how you can access the Singleton instance and call a method on it:

// Accessing the Singleton instance
CloudCodeExecutor.sharedInstance.processCloudCodeOperation()

In the code above, CloudCodeExecutor.sharedInstance is how you access a single instance of the CloudCodeExecutor class. Following that with .processCloudCodeOperation() calls the processCloudCodeOperation method on the Singleton instance, initiating the cloud code operation.

You can call this line anywhere in your code whenever you need to trigger a cloud code operation, and it will always interact with the same single instance of CloudCodeExecutor. This ensures consistency and centralization, which are key benefits of the Singleton design pattern.

// Call cloud code operation function again
CloudCodeExecutor.sharedInstance.processCloudCodeOperation()

// And again to see that class initializer was called only once
CloudCodeExecutor.sharedInstance.processCloudCodeOperation()

In the subsequent calls above, notice that even though you are calling the processCloudCodeOperation method multiple times, you are still interacting with the same single instance of CloudCodeExecutor. This showcases the essence of the Singleton design pattern in action, ensuring a single point of access and interaction regardless of where and how many times you access the Singleton instance.

Pros and Cons of Using Singletons in Swift

Singletons in Swift offer a neat way to have a single instance of a class, but like every design pattern, they have their upsides and downsides. Let’s go through them:

Pros:

  1. Single Source of Truth: Singletons provide a centralized place to manage shared resources, making your code easier to understand.
  2. Resource Efficiency: By ensuring only one instance of a class exists, Singletons help save resources, which is great for heavy objects.
  3. Global Access: The Singleton instance is accessible globally, making it easy to share resources or functionality throughout your app.
  4. Synchronization: When you need to synchronize processes between threads, Singletons come in handy by providing a single point of access.

Cons:

  1. Testing Challenges: Singletons can make unit testing tough due to shared state, leading to tests that may affect each other.
  2. Hidden Dependencies: They can create hidden dependencies in your code, making it hard to track changes and debug.
  3. Tightly Coupled Code: Singletons can lead to code that’s tightly coupled, making it harder to manage as your codebase grows.
  4. Single Point of Failure: If something goes wrong with the Singleton instance, it can affect the entire system since all parts of the code access the same instance.

Conclusion

In this tutorial, you have learned about the Singleton design pattern and how to implement it in Swift. It’s a neat way to handle shared resources in your app.

As you keep learning Swift, checking out different coding techniques is really helpful. Feel free to check out other Swift code examples to expand your knowledge and improve your coding.

Leave a Reply

Your email address will not be published. Required fields are marked *