Reputation:
to unwrap a Double from my default values, I seem to have to do it with two guard let
statements to unwrap the value safely such as in what follows:
guard let distanceAwayPreference = self.defaults.string(forKey: "distancePreference") else {
return
}
guard let doubleDAP = Double(distanceAwayPreference) else {
return
}
– because if I do it like this:
guard let DistanceAwayPreference = self.defaults.double(forKey: "distancePreference") else {
return
}
– I get the error:
Initializer for conditional binding must have Optional type, not 'Double'
Is there a better way so i can do it once, or have less code throughout my app?
Upvotes: 0
Views: 730
Reputation: 402
I think it's better to return Any from defaults instead of String. So, this way you can use optional casting.
guard let doubleDAP = self.defaults.object(forKey: "distancePreference") as? Double else {
return
}
Upvotes: 0
Reputation: 119310
The method double(forKey:)
is not returning an optional
at all. According to the documentation it returns:
The double value associated with the specified key. If the key doesn‘t exist, this method returns 0.
So you can't optional bind it to a variable. This is why you've got that error:
Initializer for conditional binding must have Optional type, not 'Double'
For less and cleaner code (when using it), you can use a simple property wrapper like:
@propertyWrapper
struct UserDefault<T> {
let key: String
let defaultValue: T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get { UserDefaults.standard.object(forKey: key) as? T ?? defaultValue }
set { UserDefaults.standard.set(newValue, forKey: key) }
}
}
Then you can have a custom helper struct like this:
struct UserDefaultsConfig {
@UserDefault("distancePreference", defaultValue: 0)
static var distancePreference: Double
}
And use it late like:
UserDefaultsConfig.distancePreference = 12
Upvotes: 2