Skip to main content

Swift API Manager -Alamofire-Refresh Token-With TestCases

  import Foundation import KeychainAccess enum APIError : Error { case accessTokenExpired case networkError // Add more error cases as needed } class APIManager { private let keychain = Keychain (service: "com.example.app.refreshToken" ) private let refreshTokenKey = "refreshToken" private var accessToken: String ? func callAPI < T : Codable >( urlString : String , method : String , parameters : [ String : Any ] ? , completion : @escaping ( Result < T , APIError >) -> Void ) { guard let url = URL (string: urlString) else { completion(.failure(.networkError)) return } var request = URLRequest (url: url) request.httpMethod = method // Add access token to the request headers if available if let token = accessToken { request.setValue( "Bearer \(token) " , forHTTPHeaderField: "Aut...

Singleton vs Dependency Injection in iOS Swift With A Simple Example

 

Singleton

Singleton: - The Singleton is a Design Pattern. That only on single instance of a class. A Singleton can be accessed from anywhere in the program, but it cannot be modified from anywhere. It can only be modified from within the Singleton. It is, therefore, a means to protect globals.

A Singleton class supports inheritance, while a Static class is a sealed class, and therefore cannot be inherited. A Singleton class can inherit from other classes, while a Static class cannot (not even from other static classes).

  • The singleton pattern increases coupling.
Disadvantages of singleton in Swift
  • The global nature leads to dependency hiding.
  • It can be difficult to unit test the code.
  • It can lead to tightly coupled code.
  • If the single Instance of the object becomes corrupted, the entire system is compromised

A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialised object.

Example: - 

class MySingleton {

static let shared = MySingleton() // Singleton instance

private init() {
// Private initializer to prevent external instantiation
}

func doSomething() {
print("Singleton: Doing something")
}
}

// Usage:
MySingleton.shared.doSomething()

Dependency Injection


Dependency Injection:- Dependency injection reduces coupling  

  • Improves code reusability.
  • Eases the unit testing of applications through mocking/stubbing injected dependencies.
  • Reduces boilerplate code because dependencies are initialized by their injector component.
  • Decouples component logic.
  • Makes it easier to extend the application classes.

Example:- 

protocol MyDependency {
func performAction()
}

class MyDependencyImplementation: MyDependency {
func performAction() {
print("Dependency: Performing an action")
}
}

class MyClass {
let dependency: MyDependency

init(dependency: MyDependency) {
self.dependency = dependency
}

func useDependency() {
dependency.performAction()
}
}

// Usage:
let dependency = MyDependencyImplementation()
let myClass = MyClass(dependency: dependency)
myClass.useDependency()


Reference

Comments