Defaults
Defaults copied to clipboard
Support initial value for optional key
I have:
extension Defaults.Keys {
static let refreshInterval = Key<TimeInterval?>("refreshInterval")
}
And I would like to specify an initial value, meaning one that is used before any value is set. This is different from default
, which is used whenever the value is nil
, which would not work here as it would make it impossible to set the value to nil
, which is the whole point of making the value optional.
What I'm thinking:
extension Defaults.Keys {
static let refreshInterval = Key<TimeInterval?>("refreshInterval", initialValue: 3600)
}
The problem is that there's no good way to differentiate whether a key unset or nil
.
-
object(forKey:)
returnsnil
whether it's unset or set tonil
. -
suite.dictionaryRepresentation().keys.contains(key)
returnsnil
whether it's unset or set tonil
. -
suite.persistentDomain(forName:).keys.contains(key)
would work, but we only have the suite instance, not the suite name. And the suite instance doesn't expose the suite name... -
CFPreferencesCopyValue
returns the true value ignoring thesuite.register
defaults, but it requires a suite name.
Possible solutions:
- Force passing a
suiteName
parameter too if you want to useinitialValue
with a non-standard suite. (and useCFPreferencesCopyValue
) - Keep track of keys that are set in an internal UserDefaults entry.
- Other ideas?
@hank121314 Any opinions on this?
IMO, Although the second solution will be more user friendly, it will create an extra space storage(internal UserDefaults).
I prefer the first one 😄. So bad we could not retrieve the suite name from suite 😠.
Yeah, I agree. The most common use-case is to use the standard suite anyway.
Seems like CFPreferencesCopyValue
does not work either, at least on macOS 13. Maybe it used to work. So it looks like we'll have to manage the state ourselves.
I'm thinking we can store it in a key called __DEFAULTS__keysThatHaveBeenSet
. It would be an array of keys that have been set once.
The init would be:
public convenience init<T>(
_ key: String,
initialValue: Value,
suite: UserDefaults = .standard
) where Value == T? {}
We would only store keys coming from this initializer.