I want to use the singleton pattern in my class which has a private init
with parameter. It also has a class function called setup
which configures
I have a slightly different solution. This relies on
.
class MySingleton {
static let shared = MySingleton()
struct Config {
var param:String
}
private static var config:Config?
class func setup(_ config:Config){
MySingleton.config = config
}
private init() {
guard let config = MySingleton.config else {
fatalError("Error - you must call setup before accessing MySingleton.shared")
}
//Regular initialisation using config
}
}
To use this, you set it up with
MySingleton.setup(MySingleton.Config(param: "Some Param"))
(Obviously you can use multiple params if needed by expanding the MySingleton.Config struct)
Then to access the singleton, you use
MySingleton.shared
I'm not wild about having to use a separate setup struct, but I like that this stays close to the recommended singleton pattern. Keeping the setup struct inside the singleton keeps things fairly clean.
Note - the shared object is a singleton. In the background, swift uses dispatchOnce to guarantee that. However there is nothing stopping you from calling setup multiple times with different configs from different threads.
At the moment, the first call to shared will 'lock' the setup.
If you want to lock things down after the first call to setup, then just call
_ = MySingleton.shared
in setup
Simple Example:
class ServerSingleton {
static let shared = ServerSingleton()
struct Config {
var host:String
}
private static var config:Config?
let host:String
class func setup(_ config:Config){
ServerSingleton.config = config
}
private init() {
guard let config = ServerSingleton.config else {
fatalError("Error - you must call setup before accessing MySingleton.shared")
}
host = config.host
}
func helpAddress() -> String {
return host+"/help.html"
}
}
ServerSingleton.setup(ServerSingleton.Config(host: "http://hobbyistsoftware.com") )
let helpAddress = ServerSingleton.shared.helpAddress()
//helpAddress is now http://hobbyistsoftware.com/help.html