How to create singleton in swift?

I'm developing this app where I want to store user's information that they enter on first screen and be able to use it in multiple application within the app.


In my research I found out that I have to create a singleton. I'm very new to swift so I was hopping someone can guide me.


This is what I have:

class UserInfo {

var userFirstName: String? 
var userLastName: String?

}

let sharedInfo = UserInfo()


Am I on right track to create singleton?

Answered by OOPer in 21129022

I should have written it clearly, but `recently` meant Swift 1.2 (comes with Xcode 6.3) and after.


Till Swift 1.1, I used something like this:

class UserInfo {
    class var sharedInfo: UserInfo {
        struct My {
            static var instance = UserInfo()
        }
        return My.instance
    }
   
    var userFirstName: String?
    var userLastName: String?
}

(Sorry, I removed all Xcode 6.1.x installations, and I cannot check if the above code actually works in Xcode 6.1.1 .)


If you don't have some specific reasons, you'd better upgrade your Xcode.

private let _sharedInstance = MyClass()

class MyClass {

     var sharedInstance {
          return _sharedInstance
     }
}


If I remember correctly, top-level vars are guaranteed to be wrapped in a dispatch_once call by the compiler. (If I'm wrong or this has changed, let me know!)

When I look at the generated code, they are wrapped in something called swift_once, which I guess does the same thing.

Both code would work, I believe, but recently preferred way would be keeping it as static property.

class UserInfo {
    static let sharedInfo = UserInfo()
   
    var userFirstName: String?
    var userLastName: String?
}

This is not working actually.


It says

"Static properties are only allowed within structs and enums; use 'class' to declare a class property"


And when I replace it with 'class', it gives me different error:

"'UserInfo' cannot be constructed because it has no accessible initializers"


I'm stuck 😟

Which version of Swift (or Xcode) are you using?

xcode version is Version 6.1.1 (6A2008a)

Accepted Answer

I should have written it clearly, but `recently` meant Swift 1.2 (comes with Xcode 6.3) and after.


Till Swift 1.1, I used something like this:

class UserInfo {
    class var sharedInfo: UserInfo {
        struct My {
            static var instance = UserInfo()
        }
        return My.instance
    }
   
    var userFirstName: String?
    var userLastName: String?
}

(Sorry, I removed all Xcode 6.1.x installations, and I cannot check if the above code actually works in Xcode 6.1.1 .)


If you don't have some specific reasons, you'd better upgrade your Xcode.

This worked! Thank you so much!

I'm not sure what line #3 is doing and the purpose of it.


Do you mind explaining?


Thanks again!

As you know, if you don't mind having shared instance in a global variable, that works so well. Just we want to encapsulate it in a class definition.


And till 1.1, Swift class could not have stored static properties, but structs could. So, we utilize other Swift feature, nested types.

Putting the struct definition inside the getter block, makes the definition very private, the struct is only visible in the block, but still can have a static property with lazy - `once`-guaranteed initialization.


The code I have shown as `till 1.1` would work in 1.2 or later, but if you write new apps in Swift 1.2 or 2, the `recent` way will be more simple and clearer.

How to create singleton in swift?
 
 
Q