[swift-users] UserDefaults with generic keys

Thierry Passeron thierry.passeron at gmail.com
Fri Jul 7 06:02:26 CDT 2017


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:

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.


More information about the swift-users mailing list