SwiftyUserDefaults icon indicating copy to clipboard operation
SwiftyUserDefaults copied to clipboard

[WIP] use DefaultsKey.defaultValue for registering user defaults

Open DivineDominion opened this issue 6 years ago • 3 comments

I'm working on macOS apps and rely on the effect of register(defaults:) a lot. It didn't bother me to register them manually, using the swifty keys in the dictionary like so: DefaultsKeys.myKey._key : 123

But now that the keys require a default value, I'd like to not duplicate using this.

Either make the defaultValue public for compatibility, I figured, or offer a convenient wrapper around the register(defaults:) method. This is a prototype for the latter.

Is this a direction you want to go?

Usage:

extension DefaultsKeys {
    static let foo = DefaultsKey<Bool>("foo", defaultValue: true)
}

Defaults.register(defaultsKeys: [ DefaultsKeys.foo, ... ])

This works thanks to a protocol that type-erases the internals of DefaultsKey<T>:

public protocol DefaultsKeyable {
    var _key: String { get }
    var _defaultValue: Any? { get }
}

It's not that convenient to have to use DefaultsKeys.foo to reference the key. But I think the DefaultsKeys class can become a protocol instead, and the new DefaultsKeyable can inherit from that, and then it should work to write .register(defaultsKeys: [ .foo, ... ])

DivineDominion avatar Apr 16 '19 07:04 DivineDominion

@DivineDominion Yeah I agree, we should make defaultValue public - no reason to hide it behind our framework if it's user-provided value anyways. Would it make the implementation easier?

Also, about making DefaultsKeys a protocol - this would make it impossible to have stored values in extension, right? We would have to make them all computed?

sunshinejr avatar Apr 16 '19 09:04 sunshinejr

Also, about making DefaultsKeys a protocol - this would make it impossible to have stored values in extension, right? We would have to make them all computed?

You're right, I totally missed that part.

DivineDominion avatar Apr 17 '19 07:04 DivineDominion

During field-testing I found there's more work to be done:

  • [ ] defaultValue of a RawRepresentable enum is an enum case, but we want to get to defaultValue.rawValue in that case
  • [ ] similarly, custom types need to pass through the serialization bridge to be converted

DivineDominion avatar Apr 19 '19 06:04 DivineDominion