I would like to initialize a variable obj by taking it from UserDefaults, which returns a String?, and if it's nil build the value and assign it.
The following code works, but, at the end, my obj is a String? while I want it to be a String (since it can't be nil at this stage).
var obj = UserDefaults.standard.string(forKey: "my_key")// Here, obj is a String?
if obj == nil {
obj = ProcessInfo.processInfo.globallyUniqueString// Returns, a String
defaults.set(obj, forKey: "my_key")
defaults.synchronize()
}
// Here, obj is still a String?
Is there a good pattern / best practice for this kind of situation ?
You can use the nil-coalescing operator ?? with an
"immediately evaluated closure":
let obj = UserDefaults.standard.string(forKey: "my_key") ?? {
let obj = ProcessInfo.processInfo.globallyUniqueString
UserDefaults.standard.set(obj, forKey: "my_key")
return obj
}()
print(obj) // Type is `String`
If the user default is not set, the closure is executed.
The closure creates and sets the user default (using a local obj
variable) and returns it to the caller, so that
it is assigned to the outer obj variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With