Swift
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Optionals
-
Section 4: Object-Oriented and Value Types
-
Section 5: Memory Management
-
Section 6: Generics and Error Handling
-
Section 7: Concurrency
-
Section 8: Working with Collections
-
Section 9: Codable and Data Handling
-
Section 10: Protocol-Oriented Programming
-
Section 11: Testing and Tooling
-
Section 12: Practical Projects
-
Section 13: Interview Practice
-
Section 14: More Practice Exercises
-
Section 15: More Standard Library
-
Section 16: Advanced Concurrency
-
Section 17: Foundation Framework Deep Dive
-
Section 18: URLSession and Networking Deep Dive
-
Section 19: Combine Framework
-
Section 20: SwiftUI Fundamentals for Swift Developers
-
Section 21: Server-Side Swift with Vapor
-
Section 22: Swift Package Manager Deep Dive
-
Section 23: Swift Concurrency Deep Dive
-
Section 24: More Language Features
-
Section 25: Error Handling Deep Dive
-
Section 26: Testing Deep Dive
-
Section 27: Data Structures and Algorithms in Swift
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Swift Macros (Swift 5.9+)
-
Section 31: Property Wrappers Ecosystem
-
Section 32: Swift Interop Deep Dive
-
Section 33: iOS App Architecture Patterns
-
Section 34: Performance and Debugging
-
Section 35: App Distribution and CI/CD
-
Section 36: More Practical Projects
-
Section 37: SwiftData and Persistence
-
Section 38: More Design Patterns
-
Section 39: More Review and Practice
-
Section 40: More Foundation Deep Dive
-
Section 41: Advanced Collections in Swift
-
Section 42: Advanced Generics Practice
-
Section 43: UIKit for Legacy and Hybrid Apps
-
Section 44: watchOS and visionOS Development Basics
-
Section 45: More Networking Patterns
-
Section 46: More Testing Practice
-
Section 47: Accessibility in Swift Apps
-
Section 48: Localization
-
Section 49: More Practical Projects Round 2
-
Section 50: Swift Charts Framework
-
Section 51: More Interview and Algorithm Practice
-
Section 52: Final Practice and Mastery
-
Section 53: Swift Compiler and Build System
-
Section 54: More Concurrency Practice
-
Section 55: App Store Guidelines and Review
-
Section 56: More Design and Architecture
164: The Singleton Pattern in Swift
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 asfalse). - Create a function
login(as name: String)that updates both properties.
Test your implementation:
- Try to create a new instance of
UserSessionManagerusingUserSessionManager()and verify that the compiler throws an error. - Access the
sharedinstance and calllogin(as: "SwiftDeveloper"). - Print the
usernamefrom a different part of your code using thesharedinstance to ensure the name was updated globally.
There are no comments for now.