Skip to content

Instantly share code, notes, and snippets.

@revblaze
Last active July 7, 2023 18:28
Show Gist options
  • Save revblaze/2328bb2d88098e8fedb4ab95709a0fc9 to your computer and use it in GitHub Desktop.
Save revblaze/2328bb2d88098e8fedb4ab95709a0fc9 to your computer and use it in GitHub Desktop.
UserDefaults template with embedded auto-completion
let defaults = UserDefaults.standard
// MARK: Keys
enum Keys: String, CaseIterable {
case firstName
case websiteUrl
case hasLaunchedAppBefore
/// The default value for a given UserDefaults key
var defaultValue: Any {
switch self {
case .firstName: return "John"
case .websiteUrl: return URL(string: "https://apple.com")
case .hasLaunchedAppBefore: return false
}
}
}
// MARK: Settings
struct Settings {
static let firstName: String = getValue(.firstName) as! String
static let websiteUrl: URL = getValue(.websiteUrl) as! URL
static var hasLaunchedAppBefore: Bool = getValue(.hasLaunchedAppBefore) as! Bool
/// Returns the value for a given UserDefaults key
static func getValue(_ forKey: Keys) -> Any {
return defaults.value(forKey: forKey.rawValue) as Any
}
/// Saves a value to a given UserDefaults key
static func saveValue(_ value: Any, forKey: Keys) {
defaults.set(value, forKey: forKey.rawValue)
}
/// Returns the default value for any given UserDefaults key
static func getDefaultValue(_ forKey: Keys) -> Any {
return forKey.defaultValue
}
/// Reverts to the default value of the given UserDefaults key
static func setDefaultValue(_ forKey: Keys) {
defaults.set(forKey.defaultValue, forKey: forKey.rawValue)
}
/// Restore all values to their default state
static func restoreAllDefaults() {
for key in Keys.allCases {
setDefaultValue(key)
}
}
}
// Iterate through all cases of Keys
extension Keys {
static var allCases: [Self] {
return Mirror(reflecting: self).children.compactMap { $0.value as? Self }
}
}
@revblaze
Copy link
Author

revblaze commented Jul 7, 2023

Explicitly using String-based values for Settings

let defaults = UserDefaults.standard

// MARK: Keys
enum Keys: String {
  case myFirstKey
  
  /// The default value for a given UserDefaults key
  var defaultValue: String {
    switch self {
    case .myFirstKey: return "[default value for myFirstKey]"
    }
  }
}

// MARK: Settings
struct Settings {
  
  static let myFirstSetting = getValue(.myFirstValue)
  
  /// Returns the value for a given UserDefaults key
  static func getValue(_ forKey: Keys) -> String {
    return defaults.value(forKey: forKey.rawValue)
  }
  /// Saves a value to a given UserDefaults key
  static func saveValue(_ value: String, forKey: Keys) {
    defaults.set(value, forKey: forKey.rawValue)
  }
  /// Returns the default value for any given UserDefaults key
  static func getDefaultValue(_ forKey: Keys) -> String {
    return forKey.defaultValue
  }
  /// Reverts to the default value of the given UserDefaults key
  static func setDefaultValue(_ forKey: Keys) {
    defaults.set(forKey.defaultValue, forKey: forKey.rawValue)
  }
  
}


// MARK: Iterating Keys
extension Keys {
  static var allCases: [Self] {
    return Mirror(reflecting: self).children.compactMap { $0.value as? Self }
  }
}

// Usage Example: Restore all defaults
extension Settings {
  /// Restore all settings to their default value
  static func restoreAllDefaults() {
    for key in Keys.allCases {
      if key.rawValue != key.defaultValue {
        setDefaultValue(key)
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment