user12363531
user12363531

Reputation:

Swift - unwrapping a Double value with a Guard let statement

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

Answers (2)

Boris
Boris

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

Mojtaba Hosseini
Mojtaba Hosseini

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

Related Questions