Here's an integrated solution for conditional binding as an extension of UserDefaults that return an optional rather than a default values if the key doesn't exist like integer, double, float = 0, or bool = false.
Other types already returning an optional are also conveniently integrated (in the same order than the API) to have a global semantic.
extension UserDefaults {
func valueOrNil<T>(forKey key: String) -> T? {
guard UserDefaults.standard.object(forKey: key) != nil else { return nil }
switch T.self {
case is URL?.Type:
return UserDefaults.standard.url(forKey: key) as! T?
case is Array<Any>?.Type:
return UserDefaults.standard.array(forKey: key) as! T?
case is Dictionary<String, Any>?.Type:
return UserDefaults.standard.dictionary(forKey: key) as! T?
case is String?.Type:
return UserDefaults.standard.string(forKey: key) as! T?
case is [String]?.Type:
return UserDefaults.standard.stringArray(forKey: key) as! T?
case is Data?.Type:
return UserDefaults.standard.data(forKey: key) as! T?
case is Bool?.Type:
return UserDefaults.standard.bool(forKey: key) as! T?
case is Int?.Type:
return UserDefaults.standard.integer(forKey: key) as! T?
case is Float?.Type:
return UserDefaults.standard.float(forKey: key) as! T?
case is Double?.Type:
return UserDefaults.standard.double(forKey: key) as! T?
default: return nil
}
}
}
Example:
if let value: Int? = UserDefaults.standard.valueOrNil(forKey: "MyKey") {
...
} else {
...
}