HomeiOS DevelopmentSwift singleton design sample - The.Swift.Dev.

Swift singleton design sample – The.Swift.Dev.


Singleton is probably the most criticized design sample of all time. Study the right manner of utilizing Swift singleton courses inside iOS initiatives.

Design patterns

Everyone seems to be bullying on the poor singleton sample, most people name it anti-pattern. However what precisely is a singleton class and why is it so dangerous?


What’s a singleton?

It is a very fashionable and generally adopted sample due to simplicity. A singleton class can solely have precisely one occasion by your entire utility lifecycle. That single occasion is simply accessible by a static property and the initialized object is often shared globally. It is like a worldwide variable. 🌏

World variables and states

Singletons have dangerous repute as a result of they share world mutable states. The worldwide key phrase is at all times feared even within the circle of skilled builders. World states & variables are the hotbed of unintended effects. World variables could be accessed from anyplace of your program so your courses that use them will turn into stateful, unsecure, tight coupled and onerous to debug. It isn’t an excellent follow to share states alongside objects by this manner for apparent causes. 🤮

Uncomfortable side effects

You must scope and isolate your variables as a lot as you’ll be able to and decrease the statefullness of your code. This may get rid of unintended effects, make your code safer to make use of. Take into account the next instance:

var world = 0


func sq.(_ x: Int) -> Int {
    world = x
    return x * x
}

world = 1;
var end result = sq.(5)
end result += world 
print(end result) 

The sq. methodology is written by another person, who needed to retailer the enter in the identical world variable for some motive. Now once you name that perform you will not be avare of this, till you have a look at his code. Think about this type of points within a undertaking with numerous oop courses written by a number of code authors… good luck with the military of BUGS! 🐛🐛🐛

The key lifetime of a singleton object

Singletons are created as soon as and stay eternally, they work nearly precisely like world variables and that is why it’s a must to be extraordinarily cautious with them. You must solely handle these states with singletons that lasts for the whole lifecycle of the app. For instance user-specific periods are often dangerous practices and you need to rethink your design. Additionally Swift isn’t thread secure by default, so in case you are working with singletons it’s a must to be ready for multi-threading points as effectively. But when they’re so problematic, should not we merely keep away from them totally? The reply is not any. 🚫


When to make use of a singleton class?

For instance UIApplication is almost certainly a singleton as a result of there must be just one utility occasion, and it ought to stay till you shut it down. That makes simply the right instance for a singleton. One other use case could be a Logger class. It is secure to make use of a singleton as a result of your utility will not behave any completely different if a logger is turned on or not. Noone else will personal or handle the logger and you may solely move info into the logger, so states cannot be tousled. Conclusion: a console or a logger class is kind of an appropriate situation for the utilization of the singleton sample. 👏

Console.default.discover("Hi there I am a singleton!")

There are a numerous “singletonish” (not every part is a real singleton object) use instances in Apple frameworks, here’s a quick listing, so you’ll be able to have just a little inspiration:

  • HTTPCookieStorage.shared
  • URLCredentialStorage.shared
  • URLSessionConfiguration.default
  • URLSession.shared
  • FileManager.default
  • Bundle.major
  • UserDefaults.customary
  • NotificationCenter.default
  • UIScreen.major
  • UIDevice.present
  • UIApplication.shared
  • MPMusicPlayerController.systemMusicPlayer
  • GKLocalPlayer.localPlayer()
  • SKPaymentQueue.default()
  • WCSession.default
  • CKContainer.default()
  • and so forth.

I’ve seen numerous supervisor courses applied as singletons, similar to community, location or core information managers, however these objects often should not be singletons, just because it may be a couple of of them. 💩

Singleton sample could be very helpful, but it surely must be used with warning

If you wish to flip one thing right into a singleton, ask your self these questions:

  • Will the rest personal, handle or be answerable for it?
  • Is there going to be precisely one occasion?
  • Will it’s a worldwide state variable?
  • Ought to I actually use a globally shared object?
  • Ought to stay by the entire app lifecycle?
  • Is there any options for it?

If the solutions is clearly a sure for every part above, then you’ll be able to “safely” use a singleton or a worldwide variable to retailer your information. 🎉🎉🎉


The way to create a singleton in Swift?

It is very easy to make a singleton object in Swift, however please at all times assume twice and think about options earlier than you apply this design sample.

class Singleton {

    static let shared = Singleton()

    non-public init() {
        
    }
}
let singleton = Singleton.shared

These days I am at all times creating one particular singleton object, that is referred to as App. This manner I can hook up each utility associated world state properties into that one singleton. The naming conference additionally helps me to reevaluate what goes into it. 💡


The way to get rid of singletons?

If there’s different manner you need to go together with that in ~90% of the instances. The commonest various answer for singletons is dependency injection. First you need to summary the singleton strategies right into a protocol, then you need to use the singleton because the default implementation if it is nonetheless wanted. Now you’ll be able to inject the singleton or a refactored object into the proper place. This manner your code could be examined with mocked objects of the protocol, even ignoring the singleton itself. 😎

typealias DataCompletionBlock = (Knowledge?) -> Void


protocol Session {
    func make(request: URLRequest, completionHandler: @escaping DataCompletionBlock)
}


extension URLSession: Session {

    func make(request: URLRequest, completionHandler: @escaping DataCompletionBlock) {
        let job = self.dataTask(with: request) { information, _, _ in
            completionHandler(information)
        }
        job.resume()
    }
}

class ApiService {

    var session: Session

    
    init(session: Session = URLSession.shared) {
        self.session = session
    }

    func load(_ request: URLRequest, completionHandler: @escaping DataCompletionBlock) {
        self.session.make(request: request, completionHandler: completionHandler)
    }
}



class MockedSession: Session {

    func make(request: URLRequest, completionHandler: @escaping DataCompletionBlock) {
        completionHandler("Mocked information response".information(utilizing: .utf8))
    }
}


func take a look at() {
    let api = ApiService(session: MockedSession())
    let request = URLRequest(url: URL(string: "https://localhost/")!)
    api.load(request) { information in
        print(String(information: information!, encoding: .utf8)!)
    }
}
take a look at()

As you’ll be able to see the singleton sample could be very simple to implement, but it surely’s actually onerous to decide about it is utility kinds. I am not saying that it is an anti-pattern, as a result of it is clearly not, however take care in case you are planning to take care of singletons. 😉

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments