595

I'm trying to work out an appropriate singleton model for usage in Swift. So far, I've been able to get a non-thread safe model working as:

class var sharedInstance: TPScopeManager {
    get {
        struct Static {
            static var instance: TPScopeManager? = nil
        }

        if !Static.instance {
            Static.instance = TPScopeManager()
        }

        return Static.instance!
    }
}

Wrapping the singleton instance in the Static struct should allow a single instance that doesn't collide with singleton instances without complex naming schemings, and it should make things fairly private. Obviously though, this model isn't thread-safe. So I tried to add dispatch_once to the whole thing:

class var sharedInstance: TPScopeManager {
    get {
        struct Static {
            static var instance: TPScopeManager? = nil
            static var token: dispatch_once_t = 0
        }

        dispatch_once(Static.token) { Static.instance = TPScopeManager() }

        return Static.instance!
    }
}

But I get a compiler error on the dispatch_once line:

Cannot convert the expression's type 'Void' to type '()'

I've tried several different variants of the syntax, but they all seem to have the same results:

dispatch_once(Static.token, { Static.instance = TPScopeManager() })

What is the proper usage of dispatch_once using Swift? I initially thought the problem was with the block due to the () in the error message, but the more I look at it, the more I think it may be a matter of getting the dispatch_once_t correctly defined.

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
David Berry
  • 40,941
  • 12
  • 84
  • 95
  • 3
    I would remove all that static code and use a readonly property with a @lazy initializer. – Sulthan Jun 03 '14 at 21:02
  • 1
    That's what I meant. Unfortunately we still don't have enough information about the internals. However, IMHO any implementation of `@lazy` should be thread safe. – Sulthan Jun 03 '14 at 21:04
  • 1
    And this way also has the advantage of not exposing the implementation to the predations of callers. – David Berry Jun 03 '14 at 21:05
  • 1
    It also doesn't seem like you can have @lazy class variables. – David Berry Jun 03 '14 at 21:08
  • Be careful! Two things to note with this approach. First, any classes that inherit from this will have to override the sharedInstance property. `Static.instance = TPScopeManager()` forces the instance type. If you use something like `Static.instance = self()` with a required initializer, the appropriate type class will be generated. Even so, and this is the important thing to note, only once for all instances in the hierarchy! First type to initialize is the type set for all instances. I don't think objective-c behaved the same. – sean woodward Jun 04 '14 at 21:19
  • @seanwoodward I've been trying to do some things with self (and/or Self) and I don't think Static.instance = self() would work. Another annoying, related difference is how class methods work. In objective-C self in a class method is the class object for the sub-class. In swift, self in a class method is the class object for the super class. – David Berry Jun 04 '14 at 22:59
  • @seanwoodward and somehow singletons of non-final classes just seems wrong anyway :) For what it's worth I did figure out how to resolve your concerns (I think) and fixed my post – David Berry Jun 04 '14 at 23:05
  • @seanwoodward On second thought, I think using `self()` just gives the wrong impression. So far I've not yet found a way that a subclass can take advantage of the sharedInstance method/property in a super class. – David Berry Jun 04 '14 at 23:55
  • Any reason to prefer a singleton class over a struct with static methods in Swift? – Ethan Oct 06 '14 at 20:57

30 Answers30

728

tl;dr: Use the class constant approach if you are using Swift 1.2 or above and the nested struct approach if you need to support earlier versions.

From my experience with Swift there are three approaches to implement the Singleton pattern that support lazy initialization and thread safety.

Class constant

class Singleton  {
   static let sharedInstance = Singleton()
}

This approach supports lazy initialization because Swift lazily initializes class constants (and variables), and is thread safe by the definition of let. This is now officially recommended way to instantiate a singleton.

Class constants were introduced in Swift 1.2. If you need to support an earlier version of Swift, use the nested struct approach below or a global constant.

Nested struct

class Singleton {
    class var sharedInstance: Singleton {
        struct Static {
            static let instance: Singleton = Singleton()
        }
        return Static.instance
    }
}

Here we are using the static constant of a nested struct as a class constant. This is a workaround for the lack of static class constants in Swift 1.1 and earlier, and still works as a workaround for the lack of static constants and variables in functions.

dispatch_once

The traditional Objective-C approach ported to Swift. I'm fairly certain there's no advantage over the nested struct approach but I'm putting it here anyway as I find the differences in syntax interesting.

class Singleton {
    class var sharedInstance: Singleton {
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: Singleton? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = Singleton()
        }
        return Static.instance!
    }
}

See this GitHub project for unit tests.

Alexander Vasenin
  • 11,437
  • 4
  • 42
  • 70
hpique
  • 119,096
  • 131
  • 338
  • 476
  • 16
    "thread safe by virtue of let" — has this been stated anywhere? I can't find mention of it in the documentation. – jtbandes Jun 18 '14 at 22:45
  • 4
    @jtbandes Constants are thread safe in all the languages I know. – hpique Jun 19 '14 at 03:31
  • 2
    @DaveWood I assume you're talking about the last approach. I'll quote myself: "I'd say it's no longer necessary to use this approach but I'm putting it here anyway as I find the differences in syntax interesting." – hpique Jun 22 '14 at 15:30
  • 1
    @hpique jtbandes asked about thread safety being mentioned in the docs. That quote above was from one of the Swift devs, so I thought it would be helpful, and almost as good as documentation. I also thought the fact that globals and statics use dispatch_once under the hood was interesting. I was originally using the dispatch_once method myself and have now switched to the nested struct approach. – Dave Wood Jun 22 '14 at 16:13
  • 1
    With the new access modifiers, is the first method now the "best"? – Joseph Duffy Jul 23 '14 at 21:47
  • @JosephDuffy I still prefer the nested struct approach, as it limits the scope of the instance variable. Once class constants are supported, I will use those instead. – hpique Jul 24 '14 at 00:18
  • great example @hpique, any approach for multiton please http://en.wikipedia.org/wiki/Multiton_pattern – user2727195 Dec 15 '14 at 03:55
  • Do you know if XCode 6.3 brings something new to this subject ? Can we now use static properties in classes for singletons ? – Frederic Adda Feb 11 '15 at 13:02
  • I have updated the project from @hpique to reflect the changes introduced with Swift 1.2, you can find my fork here: https://github.com/Dschee/SwiftSingleton – Jeehut Feb 15 '15 at 15:13
  • @FredA. Updated for Swift 1.2 – hpique Feb 19 '15 at 23:13
  • @hpique Why not just use `static let sharedInstance = Singleton()` in your "Class constant" approach? `static` properties in classes have global storage and are lazily initialised on first access, so you needn't declare your own storage and use a computed `class` variable (as of Swift 1.2). – Stuart Feb 25 '15 at 12:33
  • @hpique In your ``dispatch_once`` example will the Singleton class be lazily initialized? – Michael Apr 21 '15 at 22:08
  • 5
    Should `init` be also be declared `private` to guarantee one and only one instance of the object will ever exist throughout the app's lifetime? – Andrew May 26 '15 at 21:53
  • 2
    Apple has documented the "Class constant" approach: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID177 – Junfeng Jul 22 '15 at 03:50
  • Agree with Andrew, example should include `private init` to be a complete implementation. See also Florian's answer. – David James Aug 07 '15 at 09:39
  • what about inheritance – malhal Dec 01 '15 at 05:32
  • With the static let approach, is there a way to make sure the instance is only initiated on main thread? – hyouuu May 20 '16 at 07:23
  • 6
    In the "Class constant" approach, I'd suggest (a) declaring the class to be `final` so you don't subclass it; and (b) declaring the `init` method to be `private` so that you can't accidentally instantiate another instance somewhere. – Rob Sep 22 '16 at 01:07
  • In your unit tests, what how are you testing thread_safety using `func testSharedInstance_ThreadSafety()`? You expect the 2 instances to be identical if you do what exactly? How are they different from the tests of `testSharedInstance_Twice()`? – mfaani Jan 04 '17 at 03:54
  • What @Andrew and others claim is that in the "Class constant" implementation it is recommended to add private init() {} to prevent others from using the default '()' initializer for this class. Please check the end of this document: https://krakendev.io/blog/the-right-way-to-write-a-singleton – Ruben Marin Mar 02 '17 at 15:07
  • also make private init() – Prashant Bhayani Sep 19 '18 at 07:57
175

Since Apple has now clarified that static struct variables are initialized both lazy and wrapped in dispatch_once (see the note at the end of the post), I think my final solution is going to be:

class WithSingleton {
    class var sharedInstance: WithSingleton {
        struct Singleton {
            static let instance = WithSingleton()
        }

        return Singleton.instance
    }
}

This takes advantage of the automatic lazy, thread-safe initialization of static struct elements, safely hides the actual implementation from the consumer, keeps everything compactly compartmentalized for legibility, and eliminates a visible global variable.

Apple has clarified that lazy initializer are thread-safe, so there's no need for dispatch_once or similar protections

The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed, and is launched as dispatch_once to make sure that the initialization is atomic. This enables a cool way to use dispatch_once in your code: just declare a global variable with an initializer and mark it private.

From here

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
David Berry
  • 40,941
  • 12
  • 84
  • 95
  • 1
    To confirm: global variables have lazy, thread-safe initialization, but class variables don't. Right? – Bill Jun 06 '14 at 12:15
  • 14
    I would add that a good practice would be to declare the initializer as private: `private init() {}`, to further enforce the fact that this class is not meant to be externally instantiated. – Pascal Bourque Sep 26 '14 at 19:03
  • 1
    so static struct var initialization is lazy and thread safe, what if that static struct var is a dictionary for multitons, then we have to manually synchronize/queue calls to it for each access, right? –  Dec 31 '14 at 00:27
  • If I understand your question correctly, dictionary and array accesses are not inherently thread-safe, so you will need to use some form of thread synchronization. – David Berry Dec 31 '14 at 22:35
  • @DavidBerry How should I call a function inside this singleton class? I need a function to be called on the first call of myClass.sharedInstance. – Bhushan B Sep 08 '15 at 11:53
  • The easiest way is probably to use the compound initializer: `static let instance : WithSingleton = { let singleton = WithSingleton() ; ; return singleton }()` – David Berry Sep 08 '15 at 14:18
164

For Swift 1.2 and beyond:

class Singleton  {
   static let sharedInstance = Singleton()
}

With a proof of correctness (all credit goes here), there is little to no reason now to use any of the previous methods for singletons.

Update: This is now the official way to define singletons as described in the official docs!

As for concerns on using static vs class. static should be the one to use even when class variables become available. Singletons are not meant to be subclassed since that would result in multiple instances of the base singleton. Using static enforces this in a beautiful, Swifty way.

For Swift 1.0 and 1.1:

With the recent changes in Swift, mostly new access control methods, I am now leaning towards the cleaner way of using a global variable for singletons.

private let _singletonInstance = SingletonClass()
class SingletonClass {
  class var sharedInstance: SingletonClass {
    return _singletonInstance
  }
}

As mentioned in the Swift blog article here:

The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed, and is launched as dispatch_once to make sure that the initialization is atomic. This enables a cool way to use dispatch_once in your code: just declare a global variable with an initializer and mark it private.

This way of creating a singleton is thread safe, fast, lazy, and also bridged to ObjC for free.

Jack
  • 16,677
  • 8
  • 47
  • 51
  • 2
    Anyone reading only this answer: Remember to make the token static, otherwise the behavior is undefined. See David's edited question for the complete code. – nschum Jun 04 '14 at 23:23
  • @nschum otherwise, the behaviour is not undefined, it is just broken in a well-defined way: the block will always execute. – Michael Jun 10 '14 at 10:54
  • @Michael: The documentation states it is undefined. The current behavior is therefore coincidental. – nschum Jun 10 '14 at 17:56
  • @nschum no offence, but I wouldn't believe everything that the documentation says. for dispatch_once to behave differently in static and non-static contexts it would need to check the memory layout to see if the token is static or not. that would be pretty unusual... but anyhow, I agree that it doesn't make sense to use a non-static dispatch_once token. – Michael Jun 10 '14 at 19:46
  • 1
    That's an odd thing to say. If the documentation calls it "undefined" that just means whoever wrote the code doesn't make any promises to what it does. It has nothing to do with the code knowing if the variable is static. It just means that the current (or apparent) behavior cannot not be relied upon. – nschum Jun 11 '14 at 13:42
  • And as *why* the behavior has been deemed undefined: http://stackoverflow.com/a/19845164/168939 Apparently the memory can't ever have been non-zero, and non-static memory is eventually recycled. – nschum Jun 11 '14 at 13:42
  • Regarding your **Edit**: to reason that this construct is "thread safe" since the documentations says that the "initialization is _atomic_" is not justified. _Atomicity_ is not sufficient for thread-safety. It additionally requires that all code wrapped in the dispatch_once block uses appropriate memory barriers so that _all_ side effects on memory will be "published" to _all_ other threads. – CouchDeveloper Sep 13 '14 at 07:35
  • 6
    You might want to add `private init() {}` as initialiser of `SingletonClass`. to prevent instantiate from outside. – rintaro Sep 24 '14 at 07:38
  • ... and, adding to rintaro's observation, declaring the class to be `final` so you don't accidentally subclass it. – Rob Sep 22 '16 at 01:08
  • @rintaro 's way won't work without override keyword, and it has to call super init? – Jonny Mar 21 '17 at 02:57
47

Swift 1.2 or later now supports static variables/constants in classes. So you can just use a static constant:

class MySingleton {

    static let sharedMySingleton = MySingleton()

    private init() {
        // ...
    }
}
Sahil
  • 9,096
  • 3
  • 25
  • 29
Florian
  • 5,326
  • 4
  • 26
  • 35
35

There is a better way to do it. You can declare a global variable in your class above the class declaration like this:

var tpScopeManagerSharedInstance = TPScopeManager()

This just calls your default init or whichever init and global variables are dispatch_once by default in Swift. Then in whichever class you want to get a reference, you just do this:

var refrence = tpScopeManagerSharedInstance
// or you can just access properties and call methods directly
tpScopeManagerSharedInstance.someMethod()

So basically you can get rid of the entire block of shared instance code.

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
Kris Gellci
  • 9,539
  • 6
  • 40
  • 47
  • 3
    Why a "var" and lot a "let"? – Stephan Jun 06 '14 at 18:11
  • 1
    maybe could be a let, I only tested it out with a var. – Kris Gellci Jun 06 '14 at 18:58
  • I like this answer, however I need to access this (Singleton) from Interface Builder. Any idea on how could I access this tpScopeManagerSharedInstance from within IB?. Thanks.- – Luis Palacios Jul 20 '14 at 12:08
  • This is my preferred way of having a singleton. It has all the usual features (thread-safety & lazy instantiation) *and* it supports a very lightweight syntax: no need to write `TPScopeManager.sharedInstance.doIt()` all the time, just name your class `TPScopeManagerClass`, have this declaration next to the class `public let TPScopeManager = TPScopeManagerClass()`, and when using just write `TPScopeManager.doIt()`. Very clean! – Alex Mar 06 '15 at 22:11
  • There's nothing here to prevent creation of additional instances of `TPScopeManager`, and it is therefore *not a singleton* by definition. – Caleb Mar 15 '16 at 13:30
  • @Caleb it is a global var which would only be initialized once. This answer was also posted the week Swift came out before some updates to Swift which made for better patterns. I am leaving it as is for historical purposes. – Kris Gellci Mar 16 '16 at 23:37
28

Swift singletons are exposed in the Cocoa frameworks as class functions, e.g. NSFileManager.defaultManager(), NSNotificationCenter.defaultCenter(). So it makes more sense as a class function to mirror this behavior, rather than a class variable as some other solutions. e.g:

class MyClass {

    private static let _sharedInstance = MyClass()

    class func sharedInstance() -> MyClass {
        return _sharedInstance
    }
}

Retrieve the singleton via MyClass.sharedInstance().

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
Ryan
  • 5,416
  • 1
  • 39
  • 36
  • 1
    upvoted for the comment of LearnCocos2D :) , also for the style. – x4h1d Oct 14 '15 at 05:39
  • 2
    the global variable should be changed to a class variable via a static inside the class. – malhal Dec 01 '15 at 05:09
  • 2
    @malhal when a variable is marked private but outside a class, it's not global - but scoped only to the file it is in. A static inside the class would work pretty much the same, but i've updated the answer to use the static as you suggested, as it better groups the variable to the class if you happen to use multiple classes within the file. – Ryan Dec 02 '15 at 03:56
  • 1
    "Swift Singletons are exposed in the cocoa frameworks as class functions" ... Not in Swift 3. They're now usually `static` properties. – Rob Sep 22 '16 at 01:10
17

Per the Apple documentation, it has been repeated many times that the easiest way to do this in Swift is with a static type property:

class Singleton {
    static let sharedInstance = Singleton()
}

However, if you're looking for a way to perform additional setup beyond a simple constructor call, the secret is to use an immediately invoked closure:

class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()
        // setup code
        return instance
    }()
}

This is guaranteed to be thread-safe and lazily initialized only once.

Adrian Macneil
  • 13,017
  • 5
  • 57
  • 70
16

Swift 4+

protocol Singleton: class {
    static var sharedInstance: Self { get }
}

final class Kraken: Singleton {
    static let sharedInstance = Kraken()
    private init() {}
}
Adam Smaka
  • 5,977
  • 3
  • 50
  • 55
8

Looking at Apple's sample code I came across this pattern. I'm not sure how Swift deals with statics, but this would be thread safe in C#. I include both the property and method for Objective-C interop.

struct StaticRank {
    static let shared = RankMapping()
}

class func sharedInstance() -> RankMapping {
    return StaticRank.shared
}

class var shared:RankMapping {
    return StaticRank.shared
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user2485100
  • 89
  • 1
  • 2
  • I am pretty sure that just using this default static syntax will do the all annoying jobs. – eonil Jun 05 '14 at 04:18
  • unfortunately statics only work inside of structs, so that's why this pattern. – user2485100 Jun 05 '14 at 05:16
  • My intention was that we don't have to use `dispatch_once` stuffs. I am betting on your style. :) – eonil Jun 05 '14 at 05:24
  • Isn't `class` within a class declaration the equivalent of `static` in a struct declaration? – Russell Borogove Jun 05 '14 at 17:51
  • @Sam Yes it is. See the Apple blog entry on [Files and Initialization](https://developer.apple.com/swift/blog/?id=7) which makes it clear that both globals and static members of structs and enums benefit from this `dispatch_once` capability. – Rob Feb 13 '15 at 22:39
5

In brief,

class Manager {
    static let sharedInstance = Manager()
    private init() {}
}

You may want to read Files and Initialization

The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed, and is launched as dispatch_once to make sure that the initialization is atomic.

onmyway133
  • 45,645
  • 31
  • 257
  • 263
4

Use:

class UtilSingleton: NSObject {

    var iVal: Int = 0

    class var shareInstance: UtilSingleton {
        get {
            struct Static {
                static var instance: UtilSingleton? = nil
                static var token: dispatch_once_t = 0
            }
            dispatch_once(&Static.token, {
                Static.instance = UtilSingleton()
            })
            return Static.instance!
        }
    }
}

How to use:

UtilSingleton.shareInstance.iVal++
println("singleton new iVal = \(UtilSingleton.shareInstance.iVal)")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kingiol
  • 1,145
  • 9
  • 9
  • This is exactly the same as one of the answers I went through on the way to the current answer. Since global variables are initialized both lazy and thread-safe, there's no reason for the additional complexity. – David Berry Jun 06 '14 at 15:14
  • @David Other than not having a global variable. :) – hpique Jun 10 '14 at 05:37
  • @hpique no, exactly like one of my earlier attempts. Look at the edit history. – David Berry Jun 10 '14 at 14:47
4

If you are planning on using your Swift singleton class in Objective-C, this setup will have the compiler generate appropriate Objective-C-like header(s):

class func sharedStore() -> ImageStore {
struct Static {
    static let instance : ImageStore = ImageStore()
    }
    return Static.instance
}

Then in Objective-C class you can call your singleton the way you did it in pre-Swift days:

[ImageStore sharedStore];

This is just my simple implementation.

Michael
  • 697
  • 5
  • 11
  • This is actually more concise & correct than the other example because it is implemented the same way as other Swift singletons are. i.e: **as class functions** like `NSFileManager.defaultManager()`, but still uses the lazy thread-safe static member mechanisms of Swift. – Leslie Godwin Nov 03 '15 at 05:31
  • Cocoa generally implements these as static properties, nowadays, not as class functions. – Rob Sep 22 '16 at 01:12
  • I am aware of that, my comment is over 2 years old. Thanks for mentioning. – Michael Sep 23 '16 at 19:50
4

First solution

let SocketManager = SocketManagerSingleton();

class SocketManagerSingleton {

}

Later in your code:

func someFunction() {        
    var socketManager = SocketManager        
}

Second solution

func SocketManager() -> SocketManagerSingleton {
    return _SocketManager
}
let _SocketManager = SocketManagerSingleton();

class SocketManagerSingleton {

}

And later in your code you will be able to keep braces for less confusion:

func someFunction() {        
    var socketManager = SocketManager()        
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nicolas Manzini
  • 8,379
  • 6
  • 63
  • 81
4
final class MySingleton {
     private init() {}
     static let shared = MySingleton()
}

Then call it;

let shared = MySingleton.shared
Kemal Can Kaynak
  • 1,638
  • 14
  • 26
  • Well done for not only marking `init` as `private`, but also for making the `sharedMyModel` as `final`! For the sake of future readers, in Swift 3, we might be inclined to rename `sharedMyModel` to be simply `shared`. – Rob Nov 11 '16 at 09:16
  • This is the only correct answer, except that the override and call to super.init are erroneous and will not even compile. – Michael Morris Apr 16 '17 at 14:47
4

The best approach in Swift above 1.2 is a one-line singleton, as -

class Shared: NSObject {

    static let sharedInstance = Shared()

    private override init() { }
}

To know more detail about this approach you can visit this link.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CodeCracker
  • 461
  • 5
  • 17
  • Why a `NSObject` subclass?. Apart from that, this seems to be essentially the same as http://stackoverflow.com/a/28436202/1187415. – Martin R Apr 23 '16 at 18:12
3

I would suggest an enum, as you would use in Java, e.g.

enum SharedTPScopeManager: TPScopeManager {
    case Singleton
}
Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
Howard Lovatt
  • 968
  • 1
  • 8
  • 15
  • IMO, this is the only correct Swift way to implement Singleton. other answers are ObjC/C/C++ way – Bryan Chen Jun 30 '14 at 23:08
  • Could you elaborate on this answer? It's not clear to me where Singleton is instantiated from this snippet – Kenny Winker Jul 06 '14 at 01:57
  • @KennyWinker I don't have an Apple developer login, therefore no swift and so I can't answer when the initialisation occurs. In Java, it is on first use. Perhaps you could try it with a print on initialization and see if the print occurs at launch or after access. It will depend on how enum is implemented by the compiler. – Howard Lovatt Jul 07 '14 at 03:04
  • @KennyWinkler: Apple have just clarified how this works, see https://developer.apple.com/swift/blog/?id=7. In it they say "run the initializer for a global the first time it is referenced, similar to Java" and in particular. They also say that under the covers they are using "dispatch_once to make sure that the initialization is atomic". Therefore enum is almost certainly the way to go unless you have some fancy init to do, then a private static let is the solution. – Howard Lovatt Aug 04 '14 at 05:11
3

From Apple Docs (Swift 3.0.1),

You can simply use a static type property, which is guaranteed to be lazily initialized only once, even when accessed across multiple threads simultaneously:

class Singleton {
    static let sharedInstance = Singleton()
}

If you need to perform additional setup beyond initialization, you can assign the result of the invocation of a closure to the global constant:

class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()
        // setup code
        return instance
    }()
}
Rukshan
  • 7,902
  • 6
  • 43
  • 61
2

Just for reference, here is an example Singleton implementation of Jack Wu/hpique's Nested Struct implementation. The implementation also shows how archiving could work, as well as some accompanying functions. I couldn't find this complete of an example, so hopefully this helps somebody!

import Foundation

class ItemStore: NSObject {

    class var sharedStore : ItemStore {
        struct Singleton {
            // lazily initiated, thread-safe from "let"
            static let instance = ItemStore()
        }
        return Singleton.instance
    }

    var _privateItems = Item[]()
    // The allItems property can't be changed by other objects
    var allItems: Item[] {
        return _privateItems
    }

    init() {
        super.init()
        let path = itemArchivePath
        // Returns "nil" if there is no file at the path
        let unarchivedItems : AnyObject! = NSKeyedUnarchiver.unarchiveObjectWithFile(path)

        // If there were archived items saved, set _privateItems for the shared store equal to that
        if unarchivedItems {
            _privateItems = unarchivedItems as Array<Item>
        } 

        delayOnMainQueueFor(numberOfSeconds: 0.1, action: {
            assert(self === ItemStore.sharedStore, "Only one instance of ItemStore allowed!")
        })
    }

    func createItem() -> Item {
        let item = Item.randomItem()
        _privateItems.append(item)
        return item
    }

    func removeItem(item: Item) {
        for (index, element) in enumerate(_privateItems) {
            if element === item {
                _privateItems.removeAtIndex(index)
                // Delete an items image from the image store when the item is 
                // getting deleted
                ImageStore.sharedStore.deleteImageForKey(item.itemKey)
            }
        }
    }

    func moveItemAtIndex(fromIndex: Int, toIndex: Int) {
        _privateItems.moveObjectAtIndex(fromIndex, toIndex: toIndex)
    }

    var itemArchivePath: String {
        // Create a filepath for archiving
        let documentDirectories = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
        // Get the one document directory from that list
        let documentDirectory = documentDirectories[0] as String
        // append with the items.archive file name, then return
        return documentDirectory.stringByAppendingPathComponent("items.archive")
    }

    func saveChanges() -> Bool {
        let path = itemArchivePath
        // Return "true" on success
        return NSKeyedArchiver.archiveRootObject(_privateItems, toFile: path)
    }
}

And if you didn't recognize some of those functions, here is a little living Swift utility file I've been using:

import Foundation
import UIKit

typealias completionBlock = () -> ()

extension Array {
    func contains(#object:AnyObject) -> Bool {
        return self.bridgeToObjectiveC().containsObject(object)
    }

    func indexOf(#object:AnyObject) -> Int {
        return self.bridgeToObjectiveC().indexOfObject(object)
    }

    mutating func moveObjectAtIndex(fromIndex: Int, toIndex: Int) {
        if ((fromIndex == toIndex) || (fromIndex > self.count) ||
            (toIndex > self.count)) {
                return
        }
        // Get object being moved so it can be re-inserted
        let object = self[fromIndex]

        // Remove object from array
        self.removeAtIndex(fromIndex)

        // Insert object in array at new location
        self.insert(object, atIndex: toIndex)
    }
}

func delayOnMainQueueFor(numberOfSeconds delay:Double, action closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue()) {
            closure()
    }
}
SchoonSauce
  • 291
  • 1
  • 3
  • 14
2

In swift, you can create a singleton class following way:

class AppSingleton: NSObject {

    //Shared instance of class
    static let sharedInstance = AppSingleton()

    override init() {
        super.init()
    }
}
Vicky Prajapati
  • 137
  • 1
  • 5
1

After seeing David's implementation, it seems like there is no need to have a singleton class function instanceMethod since let is doing pretty much the same thing as a sharedInstance class method. All you need to do is declare it as a global constant and that would be it.

let gScopeManagerSharedInstance = ScopeManager()

class ScopeManager {
   // No need for a class method to return the shared instance. Use the gScopeManagerSharedInstance directly. 
}
Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
Essa A. Haddad
  • 881
  • 2
  • 9
  • 10
  • 2
    As I say in my comments, the only reason to do it is that at some point in the future you can move/hide the global variable and get more singleton-like behavior. At that point, if everything is using a consistent pattern, you can just change the singleton classes themselves without having to change the usage. – David Berry Jun 07 '14 at 04:18
1

I prefer this implementation:

class APIClient {

}

var sharedAPIClient: APIClient = {
    return APIClient()
}()

extension APIClient {
    class func sharedClient() -> APIClient {
        return sharedAPIClient
    }
}
Dark Matter
  • 3,638
  • 3
  • 14
  • 14
1

My way of implementation in Swift...

ConfigurationManager.swift

import Foundation

    let ConfigurationManagerSharedInstance = ConfigurationManager()
 class ConfigurationManager : NSObject {
    var globalDic: NSMutableDictionary = NSMutableDictionary()

class var sharedInstance:ConfigurationManager {
    return ConfigurationManagerSharedInstance

}

init() {

    super.init()

    println ("Config Init been Initiated, this will be called only onece irrespective of many calls")   

}

Access the globalDic from any screen of the application by the below.

Read:

 println(ConfigurationManager.sharedInstance.globalDic)  

Write:

 ConfigurationManager.sharedInstance.globalDic = tmpDic // tmpDict is any value that to be shared among the application
1

The only right approach is below.

final class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()
        // setup code if anything
        return instance
    }()

    private init() {}
}

To Access

let signleton = Singleton.sharedInstance

Reasons:

  • static type property is guaranteed to be lazily initialized only once, even when accessed across multiple threads simultaneously, so no need of using dispatch_once
  • Privatising the init method so instance can't be created by other classes.
  • final class as you do not want other classes to inherit Singleton class.
Ely
  • 8,259
  • 1
  • 54
  • 67
Paresh Masani
  • 7,474
  • 12
  • 73
  • 139
0
   func init() -> ClassA {
    struct Static {
        static var onceToken : dispatch_once_t = 0
        static var instance : ClassA? = nil
    }

    dispatch_once(&Static.onceToken) {
        Static.instance = ClassA()
    }

    return Static.instance!
}
DD.amor
  • 45
  • 3
  • As has been discussed at great length here, it's not necessary in swift to wrap initialization in `dispatch_once` since static variable initialization is lazy and automatically protected via `dispatch_once` Apple actually recommends using statics instead of dispatch_once for that reason. – David Berry Jan 27 '15 at 16:00
0

Swift to realize singleton in the past, is nothing more than the three ways: global variables, internal variables and dispatch_once ways.

Here are two good singleton.(note: no matter what kind of writing will must pay attention to the init () method of privatisation.Because in Swift, all the object's constructor default is public, needs to be rewritten init can be turned into private, prevent other objects of this class '()' by default initialization method to create the object.)

Method 1:

class AppManager {
    private static let _sharedInstance = AppManager()

    class func getSharedInstance() -> AppManager {
       return _sharedInstance
    }

    private init() {} // Privatizing the init method
}

// How to use?
AppManager.getSharedInstance()

Method 2:

class AppManager {
    static let sharedInstance = AppManager()

    private init() {} // Privatizing the init method
}

// How to use?
AppManager.sharedInstance
Tim
  • 1,528
  • 1
  • 11
  • 8
0

Swift 5.2

You can point to the type with Self. So:

static let shared = Self()

And should be inside a type, like:

class SomeTypeWithASingletonInstance {
   static let shared = Self()
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
-1

I required my singleton to allow inheritance, and none of these solutions actually allowed it. So I came up with this:

public class Singleton {
    private static var sharedInstanceVar = Singleton()

    public class func sharedInstance() -> Singleton {
        return sharedInstanceVar
    }
}


public class SubSingleton: Singleton {

    private static var sharedInstanceToken: dispatch_once_t = 0

    public class override func sharedInstance() -> SubSingleton {
        dispatch_once(&sharedInstanceToken) {
            sharedInstanceVar = SubSingleton()
        }
    return sharedInstanceVar as! SubSingleton
    }
}
  • This way when doing Singleton.sharedInstance() first it will return the instance of Singleton
  • When doing SubSingleton.sharedInstance() first it will return the instance of SubSingleton created.
  • If the above is done, then SubSingleton.sharedInstance() is Singleton is true and the same instance is used.

The issue with this first dirty approach is that I cannot guarantee that subclasses would implement the dispatch_once_t and make sure that sharedInstanceVar is only modified once per class.

I will try to refine this further, but it would be interesting to see if anyone has strong feelings against this (besides the fact that it is verbose and requires to manually update it).

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
RicardoDuarte
  • 728
  • 7
  • 23
-1

This is the simplest one with thread safe capabilities. No other thread can access the same singleton object even if they want. Swift 3/4

struct DataService {

    private static var _instance : DataService?

    private init() {}   //cannot initialise from outer class

    public static var instance : DataService {
        get {
            if _instance == nil {
                DispatchQueue.global().sync(flags: .barrier) {
                    if _instance == nil {
                        _instance = DataService()
                    }
                }
            }
            return _instance!
        }
    }
}
Abhishek Biswas
  • 1,125
  • 1
  • 13
  • 19
  • 2
    What is the advantage over a static type property (which is guaranteed to be lazily initialized only once, even when accessed across multiple threads simultaneously) ? – Martin R Oct 12 '17 at 13:06
-2

This is my implementation. It also prevents the programmer from creating a new instance:

let TEST = Test()

class Test {

    private init() {
        // This is a private (!) constructor
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yedidya Reiss
  • 5,316
  • 2
  • 17
  • 19
-2

I use the following syntax:

public final class Singleton {    
    private class func sharedInstance() -> Singleton {
        struct Static {
            //Singleton instance.
            static let sharedInstance = Singleton()
        }
        return Static.sharedInstance
    }

    private init() { }

    class var instance: Singleton {
        return sharedInstance()
    }
}

This works from Swift 1.2 up to 4, and has several advantages:

  1. Reminds the user not to subclass implementation
  2. Prevents creation of additional instances
  3. Ensures lazy creation and unique instantiation
  4. Shortens syntax (avoids ()) by allowing to access instance as Singleton.instance
Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34