Here's yet another alternative. I read an article doing this very thing a while back, it might be interesting to you: http://radex.io/swift/nsuserdefaults/static/. It makes the key type a class instead, and inherits from a non-generic parent class to which it adds the static properties.
The gist of it is roughly like this (although the article uses subscript, which does not allow for a generic implementation so I use a get/set approach here for brevity): ``` class DefaultsKeys {} final class DefaultsKey<T>: DefaultsKeys { let value: String init(_ value: String) { self.value = value } } extension UserDefaults { func get<T>(_ key: DefaultsKey<T>) -> T? { return object(forKey: key.value) as? T } func set<T>(_ key: DefaultsKey<T>, to value: T) { set(value, forKey: key.value) } } extension DefaultsKeys { static let version = DefaultsKey<String>("version") } let defaults = UserDefaults.standard defaults.set(.version, to: "1.0") let version = defaults.get(.version) print(version ?? "N/A") ``` On Fri, 7 Jul 2017 at 14:00 Vladimir.S via swift-users < swift-users@swift.org> wrote: > On 07.07.2017 14:02, Thierry Passeron via swift-users wrote: > > Hi Everyone, > > > > Using Swift 3.1, I was wondering if I could come up with something > largely inspired by Notification.Name to help me deal with UserDefaults so > I started by doing something like: > > The only kind of solution I was able to implement, is with calculated > properties in > extension. Hope this have any sense and most likely can be improved(code > from swift > sandbox): > > struct DefaultsKey<T> { > var rawValue : String > > init(_ name: String) { > rawValue = name > } > } > > extension DefaultsKey { > static var version : DefaultsKey<String> { return > DefaultsKey<String>("version") } > static var code : DefaultsKey<Int> { return > DefaultsKey<Int>("code") } > } > > func UserDefaults_standard_object(forKey: String) -> Any? { > switch forKey { > case "version" : return "1.0.0" > case "code" : return 12345 > default : return nil > } > } > > func Defaults<T>(_ key: DefaultsKey<T>) -> T? { > return UserDefaults_standard_object(forKey: key.rawValue) as? T > } > > let version = Defaults(.version) > let code = Defaults(.code) > > print(version ?? "-no value-", type(of: version)) // 1.0.0 Optional<String> > print(code ?? "-no value-", type(of: code)) // 12345 Optional<Int> > > > > > > > public struct DefaultsKey: RawRepresentable, Equatable, Hashable, > Comparable { > > > > public var rawValue: String > > public var hashValue: Int { return rawValue.hash } > > > > public init(_ rawValue: String) { self.rawValue = rawValue } > > public init(rawValue: String) { self.rawValue = rawValue } > > > > /* Protocols implementation .. */ > > } > > > > Now I can make extensions like: > > > > extension DefaultsKey { > > static let version = DefaultsKey("version ») > > } > > > > And use it to query the UserDefaults. > > > > public func Defaults<T>(_ key: DefaultsKey) -> T? { > > return UserDefaults.standard.object(forKey: key.rawValue) as? T > > } > > > > let version: String? = Defaults(.version) > > > > Nice, concise, I love it… > > > > But It could be even better to let the compiler check the return type of > the UserDefault for the DefaultKey that I ask if only I could create the > key and bind it to a type. So I tried this: > > > > public struct DefaultsKey<T>: RawRepresentable, Equatable, Hashable, > Comparable { > > … > > } > > > > extension DefaultsKey { > > static let version = DefaultsKey<String>("version ») > > } > > > > But this doesn’t compile: > > error: static stored properties not supported in generic types > > > > I guess I could keep all the keys outside an extension scope but then it > would not be as concise as with Notification.Name > > > > Please let me know if there is indeed a generic way to solve this. Any > help would be greatly appreciated. > > Thanks in advance. > > > > Thierry. > > _______________________________________________ > > swift-users mailing list > > swift-users@swift.org > > https://lists.swift.org/mailman/listinfo/swift-users > > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users